# Importing all libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
# Création du DataFrame fictif
data = {
'idclient': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2],
'année': [2020, 2020, 2020, 2021, 2021, 2021, 2020, 2020, 2020, 2021, 2021, 2021],
'mois': [10, 11, 12, 1, 2, 3, 10, 11, 12, 1, 2, 3],
'code_operation': [515, 520, 525, 530, 515, 155, 515, 520, 525, 530, 515, 540]
}
df = pd.DataFrame(data)
# Triez le DataFrame par client, année et mois
df = df.sort_values(['idclient', 'année', 'mois'])
# Ajoutez une colonne pour indiquer si le code d'opération 515 est présent pour chaque trimestre
df['code_515_present'] = 0 #N
# Groupement par client
#grouped = df.groupby('idclient')
# Utilisez une fenêtre glissante avec rolling pour vérifier chaque trimestre
df['code_515_present'] = df.groupby('idclient')['code_operation'].rolling(window=3, min_periods=1).apply(lambda x: 1 if any(x == 515) else 0)\
.reset_index(0, drop=True)
# Affichage du DataFrame résultant
print(df)
idclient année mois code_operation code_515_present 0 1 2020 10 515 1.0 6 1 2020 10 515 1.0 1 1 2020 11 520 1.0 7 1 2020 11 520 1.0 2 1 2020 12 525 0.0 8 1 2020 12 525 0.0 3 1 2021 1 530 0.0 9 1 2021 1 530 0.0 4 1 2021 2 515 1.0 5 1 2021 3 155 1.0 10 2 2021 2 515 1.0 11 2 2021 3 540 1.0
df.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 12 entries, 0 to 11 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 idclient 12 non-null int64 1 année 12 non-null int64 2 mois 12 non-null int64 3 code_operation 12 non-null int64 4 code_515_present 12 non-null float64 dtypes: float64(1), int64(4) memory usage: 576.0 bytes
path = 'archive/UCI_Credit_Card.csv'
df = pd.read_csv(path)
df.head()
| ID | LIMIT_BAL | SEX | EDUCATION | MARRIAGE | AGE | PAY_0 | PAY_2 | PAY_3 | PAY_4 | ... | BILL_AMT4 | BILL_AMT5 | BILL_AMT6 | PAY_AMT1 | PAY_AMT2 | PAY_AMT3 | PAY_AMT4 | PAY_AMT5 | PAY_AMT6 | default.payment.next.month | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 20000.0 | 2 | 2 | 1 | 24 | 2 | 2 | -1 | -1 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 689.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1 |
| 1 | 2 | 120000.0 | 2 | 2 | 2 | 26 | -1 | 2 | 0 | 0 | ... | 3272.0 | 3455.0 | 3261.0 | 0.0 | 1000.0 | 1000.0 | 1000.0 | 0.0 | 2000.0 | 1 |
| 2 | 3 | 90000.0 | 2 | 2 | 2 | 34 | 0 | 0 | 0 | 0 | ... | 14331.0 | 14948.0 | 15549.0 | 1518.0 | 1500.0 | 1000.0 | 1000.0 | 1000.0 | 5000.0 | 0 |
| 3 | 4 | 50000.0 | 2 | 2 | 1 | 37 | 0 | 0 | 0 | 0 | ... | 28314.0 | 28959.0 | 29547.0 | 2000.0 | 2019.0 | 1200.0 | 1100.0 | 1069.0 | 1000.0 | 0 |
| 4 | 5 | 50000.0 | 1 | 2 | 1 | 57 | -1 | 0 | -1 | 0 | ... | 20940.0 | 19146.0 | 19131.0 | 2000.0 | 36681.0 | 10000.0 | 9000.0 | 689.0 | 679.0 | 0 |
5 rows × 25 columns
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 30000 entries, 0 to 29999 Data columns (total 25 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID 30000 non-null int64 1 LIMIT_BAL 30000 non-null float64 2 SEX 30000 non-null int64 3 EDUCATION 30000 non-null int64 4 MARRIAGE 30000 non-null int64 5 AGE 30000 non-null int64 6 PAY_0 30000 non-null int64 7 PAY_2 30000 non-null int64 8 PAY_3 30000 non-null int64 9 PAY_4 30000 non-null int64 10 PAY_5 30000 non-null int64 11 PAY_6 30000 non-null int64 12 BILL_AMT1 30000 non-null float64 13 BILL_AMT2 30000 non-null float64 14 BILL_AMT3 30000 non-null float64 15 BILL_AMT4 30000 non-null float64 16 BILL_AMT5 30000 non-null float64 17 BILL_AMT6 30000 non-null float64 18 PAY_AMT1 30000 non-null float64 19 PAY_AMT2 30000 non-null float64 20 PAY_AMT3 30000 non-null float64 21 PAY_AMT4 30000 non-null float64 22 PAY_AMT5 30000 non-null float64 23 PAY_AMT6 30000 non-null float64 24 default.payment.next.month 30000 non-null int64 dtypes: float64(13), int64(12) memory usage: 5.7 MB
df.isnull().sum()
ID 0 LIMIT_BAL 0 SEX 0 EDUCATION 0 MARRIAGE 0 AGE 0 PAY_0 0 PAY_2 0 PAY_3 0 PAY_4 0 PAY_5 0 PAY_6 0 BILL_AMT1 0 BILL_AMT2 0 BILL_AMT3 0 BILL_AMT4 0 BILL_AMT5 0 BILL_AMT6 0 PAY_AMT1 0 PAY_AMT2 0 PAY_AMT3 0 PAY_AMT4 0 PAY_AMT5 0 PAY_AMT6 0 default.payment.next.month 0 dtype: int64
df.describe()
| ID | LIMIT_BAL | SEX | EDUCATION | MARRIAGE | AGE | PAY_0 | PAY_2 | PAY_3 | PAY_4 | ... | BILL_AMT4 | BILL_AMT5 | BILL_AMT6 | PAY_AMT1 | PAY_AMT2 | PAY_AMT3 | PAY_AMT4 | PAY_AMT5 | PAY_AMT6 | default.payment.next.month | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | ... | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 | 3.000000e+04 | 30000.00000 | 30000.000000 | 30000.000000 | 30000.000000 | 30000.000000 |
| mean | 15000.500000 | 167484.322667 | 1.603733 | 1.853133 | 1.551867 | 35.485500 | -0.016700 | -0.133767 | -0.166200 | -0.220667 | ... | 43262.948967 | 40311.400967 | 38871.760400 | 5663.580500 | 5.921163e+03 | 5225.68150 | 4826.076867 | 4799.387633 | 5215.502567 | 0.221200 |
| std | 8660.398374 | 129747.661567 | 0.489129 | 0.790349 | 0.521970 | 9.217904 | 1.123802 | 1.197186 | 1.196868 | 1.169139 | ... | 64332.856134 | 60797.155770 | 59554.107537 | 16563.280354 | 2.304087e+04 | 17606.96147 | 15666.159744 | 15278.305679 | 17777.465775 | 0.415062 |
| min | 1.000000 | 10000.000000 | 1.000000 | 0.000000 | 0.000000 | 21.000000 | -2.000000 | -2.000000 | -2.000000 | -2.000000 | ... | -170000.000000 | -81334.000000 | -339603.000000 | 0.000000 | 0.000000e+00 | 0.00000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 7500.750000 | 50000.000000 | 1.000000 | 1.000000 | 1.000000 | 28.000000 | -1.000000 | -1.000000 | -1.000000 | -1.000000 | ... | 2326.750000 | 1763.000000 | 1256.000000 | 1000.000000 | 8.330000e+02 | 390.00000 | 296.000000 | 252.500000 | 117.750000 | 0.000000 |
| 50% | 15000.500000 | 140000.000000 | 2.000000 | 2.000000 | 2.000000 | 34.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | ... | 19052.000000 | 18104.500000 | 17071.000000 | 2100.000000 | 2.009000e+03 | 1800.00000 | 1500.000000 | 1500.000000 | 1500.000000 | 0.000000 |
| 75% | 22500.250000 | 240000.000000 | 2.000000 | 2.000000 | 2.000000 | 41.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | ... | 54506.000000 | 50190.500000 | 49198.250000 | 5006.000000 | 5.000000e+03 | 4505.00000 | 4013.250000 | 4031.500000 | 4000.000000 | 0.000000 |
| max | 30000.000000 | 1000000.000000 | 2.000000 | 6.000000 | 3.000000 | 79.000000 | 8.000000 | 8.000000 | 8.000000 | 8.000000 | ... | 891586.000000 | 927171.000000 | 961664.000000 | 873552.000000 | 1.684259e+06 | 896040.00000 | 621000.000000 | 426529.000000 | 528666.000000 | 1.000000 |
8 rows × 25 columns
Dependent Variable:
#renaming for better convinience
df['IsDefaulter'] =df ['default.payment.next.month']
df.drop('default.payment.next.month',axis = 1)
# df.rename({'default.payment.next.month' : 'IsDefaulter'}, inplace=True)
| ID | LIMIT_BAL | SEX | EDUCATION | MARRIAGE | AGE | PAY_0 | PAY_2 | PAY_3 | PAY_4 | ... | BILL_AMT4 | BILL_AMT5 | BILL_AMT6 | PAY_AMT1 | PAY_AMT2 | PAY_AMT3 | PAY_AMT4 | PAY_AMT5 | PAY_AMT6 | IsDefaulter | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 20000.0 | 2 | 2 | 1 | 24 | 2 | 2 | -1 | -1 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 689.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1 |
| 1 | 2 | 120000.0 | 2 | 2 | 2 | 26 | -1 | 2 | 0 | 0 | ... | 3272.0 | 3455.0 | 3261.0 | 0.0 | 1000.0 | 1000.0 | 1000.0 | 0.0 | 2000.0 | 1 |
| 2 | 3 | 90000.0 | 2 | 2 | 2 | 34 | 0 | 0 | 0 | 0 | ... | 14331.0 | 14948.0 | 15549.0 | 1518.0 | 1500.0 | 1000.0 | 1000.0 | 1000.0 | 5000.0 | 0 |
| 3 | 4 | 50000.0 | 2 | 2 | 1 | 37 | 0 | 0 | 0 | 0 | ... | 28314.0 | 28959.0 | 29547.0 | 2000.0 | 2019.0 | 1200.0 | 1100.0 | 1069.0 | 1000.0 | 0 |
| 4 | 5 | 50000.0 | 1 | 2 | 1 | 57 | -1 | 0 | -1 | 0 | ... | 20940.0 | 19146.0 | 19131.0 | 2000.0 | 36681.0 | 10000.0 | 9000.0 | 689.0 | 679.0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 29995 | 29996 | 220000.0 | 1 | 3 | 1 | 39 | 0 | 0 | 0 | 0 | ... | 88004.0 | 31237.0 | 15980.0 | 8500.0 | 20000.0 | 5003.0 | 3047.0 | 5000.0 | 1000.0 | 0 |
| 29996 | 29997 | 150000.0 | 1 | 3 | 2 | 43 | -1 | -1 | -1 | -1 | ... | 8979.0 | 5190.0 | 0.0 | 1837.0 | 3526.0 | 8998.0 | 129.0 | 0.0 | 0.0 | 0 |
| 29997 | 29998 | 30000.0 | 1 | 2 | 2 | 37 | 4 | 3 | 2 | -1 | ... | 20878.0 | 20582.0 | 19357.0 | 0.0 | 0.0 | 22000.0 | 4200.0 | 2000.0 | 3100.0 | 1 |
| 29998 | 29999 | 80000.0 | 1 | 3 | 1 | 41 | 1 | -1 | 0 | 0 | ... | 52774.0 | 11855.0 | 48944.0 | 85900.0 | 3409.0 | 1178.0 | 1926.0 | 52964.0 | 1804.0 | 1 |
| 29999 | 30000 | 50000.0 | 1 | 2 | 1 | 46 | 0 | 0 | 0 | 0 | ... | 36535.0 | 32428.0 | 15313.0 | 2078.0 | 1800.0 | 1430.0 | 1000.0 | 1000.0 | 1000.0 | 1 |
30000 rows × 25 columns
plt.figure(figsize=(10,5))
sns.countplot(x = 'IsDefaulter', data = df)
<AxesSubplot:xlabel='IsDefaulter', ylabel='count'>
df['IsDefaulter'].value_counts()
0 23364 1 6636 Name: IsDefaulter, dtype: int64
df['SEX'].value_counts()
2 18112 1 11888 Name: SEX, dtype: int64
df['EDUCATION'].value_counts()
2 14030 1 10585 3 4917 5 280 4 123 6 51 0 14 Name: EDUCATION, dtype: int64
fil = (df['EDUCATION'] == 5) | (df['EDUCATION'] == 6) | (df['EDUCATION'] == 0)
df.loc[fil, 'EDUCATION'] = 4
df['EDUCATION'].value_counts()
2 14030 1 10585 3 4917 5 280 4 123 6 51 0 14 Name: EDUCATION, dtype: int64
fil = df['MARRIAGE'] == 0
df.loc[fil, 'MARRIAGE'] = 3
df['MARRIAGE'].value_counts()
2 15964 1 13659 3 323 0 54 Name: MARRIAGE, dtype: int64
categorical_features = ['SEX', 'EDUCATION', 'MARRIAGE']
df_cat = df[categorical_features]
df_cat['Defaulter'] = df['IsDefaulter']
df_cat.replace({'SEX': {1 : 'MALE', 2 : 'FEMALE'},
'EDUCATION' : {1 : 'graduate school', 2 : 'university', 3 : 'high school', 4 : 'others'},
'MARRIAGE' : {1 : 'married', 2 : 'single', 3 : 'others'}}, inplace = True)
df_cat
| SEX | EDUCATION | MARRIAGE | Defaulter | |
|---|---|---|---|---|
| 0 | FEMALE | university | married | 1 |
| 1 | FEMALE | university | single | 1 |
| 2 | FEMALE | university | single | 0 |
| 3 | FEMALE | university | married | 0 |
| 4 | MALE | university | married | 0 |
| ... | ... | ... | ... | ... |
| 29995 | MALE | high school | married | 0 |
| 29996 | MALE | high school | single | 0 |
| 29997 | MALE | university | single | 1 |
| 29998 | MALE | high school | married | 1 |
| 29999 | MALE | university | married | 1 |
30000 rows × 4 columns
df[col].value_counts().plot(kind="pie",ax = axes[0],subplots=True)
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) File ~\anaconda3\lib\site-packages\pandas\core\indexes\base.py:3621, in Index.get_loc(self, key, method, tolerance) 3620 try: -> 3621 return self._engine.get_loc(casted_key) 3622 except KeyError as err: File ~\anaconda3\lib\site-packages\pandas\_libs\index.pyx:136, in pandas._libs.index.IndexEngine.get_loc() File ~\anaconda3\lib\site-packages\pandas\_libs\index.pyx:163, in pandas._libs.index.IndexEngine.get_loc() File pandas\_libs\hashtable_class_helper.pxi:5198, in pandas._libs.hashtable.PyObjectHashTable.get_item() File pandas\_libs\hashtable_class_helper.pxi:5206, in pandas._libs.hashtable.PyObjectHashTable.get_item() KeyError: 'PAY_APR' The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) Input In [215], in <cell line: 1>() ----> 1 df[col].value_counts().plot(kind="pie",ax = axes[0],subplots=True) File ~\anaconda3\lib\site-packages\pandas\core\frame.py:3505, in DataFrame.__getitem__(self, key) 3503 if self.columns.nlevels > 1: 3504 return self._getitem_multilevel(key) -> 3505 indexer = self.columns.get_loc(key) 3506 if is_integer(indexer): 3507 indexer = [indexer] File ~\anaconda3\lib\site-packages\pandas\core\indexes\base.py:3623, in Index.get_loc(self, key, method, tolerance) 3621 return self._engine.get_loc(casted_key) 3622 except KeyError as err: -> 3623 raise KeyError(key) from err 3624 except TypeError: 3625 # If we have a listlike key, _check_indexing_error will raise 3626 # InvalidIndexError. Otherwise we fall through and re-raise 3627 # the TypeError. 3628 self._check_indexing_error(key) KeyError: 'PAY_APR'
import matplotlib.pyplot as plt
import seaborn as sns
# Liste des colonnes catégorielles
#categorical_features = ['professon_code', 'compte_joint', 'compte_actif', 'compte_ferme']
# Boucle à travers les colonnes catégorielles
for col in categorical_features:
plt.figure(figsize=(13, 6))
# Créer une grille de sous-graphiques
gs = plt.GridSpec(1, 2, width_ratios=[2, 3])
# Premier sous-graphique : diagramme circulaire
ax0 = plt.subplot(gs[0])
df[col].value_counts().plot(kind="pie", ax=ax0)
ax0.set_title(f'Distribution de {col}')
ax0.set_ylabel('')
# Deuxième sous-graphique : diagramme à barres empilées
ax1 = plt.subplot(gs[1])
sns.countplot(x=col, hue='Defaulter', data=df_cat, ax=ax1)
ax1.set_title(f'Distribution de {col} par défaut')
ax1.set_xlabel(col)
ax1.set_ylabel('Nombre de clients')
ax1.legend(title='Défaut', labels=['Non', 'Oui'])
# Ajuster l'espace entre les sous-graphiques
plt.tight_layout()
plt.show()
# Boucle à travers les colonnes catégorielles
for col in categorical_features:
plt.figure(figsize=(16, 6))
# Grouper les données par colonne et défaut
grouped_data = df_cat.groupby([col, 'Defaulter']).size().unstack()
total_counts = grouped_data.sum(axis=1)
# Calculer les pourcentages
percentages = grouped_data.divide(total_counts, axis=0) * 100
# Générer le graphique empilé
ax = percentages.plot(kind='bar', stacked=True, color=['#24b1d1', '#ae24d1'])
# Ajouter les annotations de pourcentage
for i, (non_def, def_) in enumerate(zip(percentages[0], percentages[1])):
total = non_def + def_
ax.text(i, non_def / 2, f'{non_def:.1f}%', ha='center', va='center', color='w', fontsize=8)
ax.text(i, non_def + def_ / 2, f'{def_:.1f}%', ha='center', va='center', color='w', fontsize=8)
plt.title(f'Répartition des clients par {col} en fonction du défaut')
plt.xlabel(col)
plt.ylabel('Pourcentage de clients')
plt.legend(title='Défaut')
plt.tight_layout()
plt.show()
<Figure size 1152x432 with 0 Axes>
<Figure size 1152x432 with 0 Axes>
<Figure size 1152x432 with 0 Axes>
for col in categorical_features:
plt.figure(figsize=(10,5))
fig, axes = plt.subplots(ncols=2,figsize=(13,8))
df[col].value_counts().plot(kind="pie",ax = axes[0],subplots=True)
sns.countplot(x = col, hue = 'Defaulter', data = df_cat)
<Figure size 720x360 with 0 Axes>
<Figure size 720x360 with 0 Axes>
<Figure size 720x360 with 0 Axes>
sns.barplot(x='IsDefaulter', y='LIMIT_BAL', data=df)
<AxesSubplot:xlabel='IsDefaulter', ylabel='LIMIT_BAL'>
Q1 (premier quartile) : Le premier quartile divise les données en deux parties égales, où 25% des valeurs se situent en dessous de Q1. Cela signifie que 25% des données sont inférieures à Q1.
Q2 (deuxième quartile) : Q2 est simplement une autre appellation pour la médiane. Il divise les données en deux parties égales, où 50% des valeurs se situent en dessous de Q2 et 50% des valeurs se situent au-dessus de Q2.
Q3 (troisième quartile) : Le troisième quartile divise les données en deux parties égales, où 75% des valeurs se situent en dessous de Q3. Cela signifie que 25% des données sont supérieures à Q3
from IPython.display import Image
Image(filename='img.jpg')
plt.figure(figsize=(10,10)) ax = sns.boxplot(x="IsDefaulter", y="LIMIT_BAL", data=df)
#renaming columns
df.rename(columns={'PAY_0':'PAY_SEPT','PAY_2':'PAY_AUG','PAY_3':'PAY_JUL','PAY_4':'PAY_JUN','PAY_5':'PAY_MAY','PAY_6':'PAY_APR'},inplace=True)
df.rename(columns={'BILL_AMT1':'BILL_AMT_SEPT','BILL_AMT2':'BILL_AMT_AUG','BILL_AMT3':'BILL_AMT_JUL','BILL_AMT4':'BILL_AMT_JUN','BILL_AMT5':'BILL_AMT_MAY','BILL_AMT6':'BILL_AMT_APR'}, inplace = True)
df.rename(columns={'PAY_AMT1':'PAY_AMT_SEPT','PAY_AMT2':'PAY_AMT_AUG','PAY_AMT3':'PAY_AMT_JUL','PAY_AMT4':'PAY_AMT_JUN','PAY_AMT5':'PAY_AMT_MAY','PAY_AMT6':'PAY_AMT_APR'},inplace=True)
df.head()
| ID | LIMIT_BAL | SEX | EDUCATION | MARRIAGE | AGE | PAY_SEPT | PAY_AUG | PAY_JUL | PAY_JUN | ... | BILL_AMT_MAY | BILL_AMT_APR | PAY_AMT_SEPT | PAY_AMT_AUG | PAY_AMT_JUL | PAY_AMT_JUN | PAY_AMT_MAY | PAY_AMT_APR | default.payment.next.month | IsDefaulter | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 20000.0 | 2 | 2 | 1 | 24 | 2 | 2 | -1 | -1 | ... | 0.0 | 0.0 | 0.0 | 689.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1 | 1 |
| 1 | 2 | 120000.0 | 2 | 2 | 2 | 26 | -1 | 2 | 0 | 0 | ... | 3455.0 | 3261.0 | 0.0 | 1000.0 | 1000.0 | 1000.0 | 0.0 | 2000.0 | 1 | 1 |
| 2 | 3 | 90000.0 | 2 | 2 | 2 | 34 | 0 | 0 | 0 | 0 | ... | 14948.0 | 15549.0 | 1518.0 | 1500.0 | 1000.0 | 1000.0 | 1000.0 | 5000.0 | 0 | 0 |
| 3 | 4 | 50000.0 | 2 | 2 | 1 | 37 | 0 | 0 | 0 | 0 | ... | 28959.0 | 29547.0 | 2000.0 | 2019.0 | 1200.0 | 1100.0 | 1069.0 | 1000.0 | 0 | 0 |
| 4 | 5 | 50000.0 | 1 | 2 | 1 | 57 | -1 | 0 | -1 | 0 | ... | 19146.0 | 19131.0 | 2000.0 | 36681.0 | 10000.0 | 9000.0 | 689.0 | 679.0 | 0 | 0 |
5 rows × 26 columns
df['AGE'].value_counts()
df['AGE']=df['AGE'].astype('int')
fig, axes = plt.subplots(ncols=2,figsize=(20,10))
Day_df=df['AGE'].value_counts().reset_index()
df['AGE'].value_counts().plot(kind="pie",ax = axes[0],subplots=True)
sns.barplot(x='index',y='AGE',data=Day_df,ax = axes[1],orient='v')
<AxesSubplot:xlabel='index', ylabel='AGE'>
df.groupby('IsDefaulter')['AGE'].mean()
IsDefaulter 0 35.417266 1 35.725738 Name: AGE, dtype: float64
df = df.astype('int')
plt.figure(figsize=(10,10))
ax = sns.boxplot(x="IsDefaulter", y="AGE", data=df)
bill_amnt_df = df[['BILL_AMT_SEPT', 'BILL_AMT_AUG', 'BILL_AMT_JUL', 'BILL_AMT_JUN', 'BILL_AMT_MAY', 'BILL_AMT_APR']]
sns.pairplot(data = bill_amnt_df)
<seaborn.axisgrid.PairGrid at 0x1bd20a92280>
pay_col = ['PAY_SEPT', 'PAY_AUG', 'PAY_JUL', 'PAY_JUN', 'PAY_MAY', 'PAY_APR']
for col in pay_col:
plt.figure(figsize=(10,5))
sns.countplot(x = col, hue = 'IsDefaulter', data = df)
pay_amnt_df = df[['PAY_AMT_SEPT', 'PAY_AMT_AUG', 'PAY_AMT_JUL', 'PAY_AMT_JUN', 'PAY_AMT_MAY', 'PAY_AMT_APR', 'IsDefaulter']]
sns.pairplot(data = pay_amnt_df, hue='IsDefaulter')
<seaborn.axisgrid.PairGrid at 0x1bd224fab50>
from imblearn.over_sampling import SMOTE
smote = SMOTE()
# fit predictor and target variable
x_smote, y_smote = smote.fit_resample(df.iloc[:,0:-1], df['IsDefaulter'])
print('Original dataset shape', len(df))
print('Resampled dataset shape', len(y_smote))
Original dataset shape 30000 Resampled dataset shape 46728
y_smote
0 1
1 1
2 0
3 0
4 0
..
46723 1
46724 1
46725 1
46726 1
46727 1
Name: IsDefaulter, Length: 46728, dtype: int32
columns = list(df.columns)
columns
['ID', 'LIMIT_BAL', 'SEX', 'EDUCATION', 'MARRIAGE', 'AGE', 'PAY_SEPT', 'PAY_AUG', 'PAY_JUL', 'PAY_JUN', 'PAY_MAY', 'PAY_APR', 'BILL_AMT_SEPT', 'BILL_AMT_AUG', 'BILL_AMT_JUL', 'BILL_AMT_JUN', 'BILL_AMT_MAY', 'BILL_AMT_APR', 'PAY_AMT_SEPT', 'PAY_AMT_AUG', 'PAY_AMT_JUL', 'PAY_AMT_JUN', 'PAY_AMT_MAY', 'PAY_AMT_APR', 'default.payment.next.month', 'IsDefaulter']
columns.pop()
balance_df = pd.DataFrame(x_smote, columns=columns)
balance_df['IsDefaulter'] = y_smote
sns.countplot('IsDefaulter', data = balance_df)
<AxesSubplot:xlabel='IsDefaulter', ylabel='count'>
balance_df[balance_df['IsDefaulter']==1]
| ID | LIMIT_BAL | SEX | EDUCATION | MARRIAGE | AGE | PAY_SEPT | PAY_AUG | PAY_JUL | PAY_JUN | ... | BILL_AMT_MAY | BILL_AMT_APR | PAY_AMT_SEPT | PAY_AMT_AUG | PAY_AMT_JUL | PAY_AMT_JUN | PAY_AMT_MAY | PAY_AMT_APR | default.payment.next.month | IsDefaulter | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 20000 | 2 | 2 | 1 | 24 | 2 | 2 | -1 | -1 | ... | 0 | 0 | 0 | 689 | 0 | 0 | 0 | 0 | 1 | 1 |
| 1 | 2 | 120000 | 2 | 2 | 2 | 26 | -1 | 2 | 0 | 0 | ... | 3455 | 3261 | 0 | 1000 | 1000 | 1000 | 0 | 2000 | 1 | 1 |
| 13 | 14 | 70000 | 1 | 2 | 2 | 30 | 1 | 2 | 2 | 0 | ... | 36137 | 36894 | 3200 | 0 | 3000 | 3000 | 1500 | 0 | 1 | 1 |
| 16 | 17 | 20000 | 1 | 1 | 2 | 24 | 0 | 0 | 2 | 2 | ... | 17905 | 19104 | 3200 | 0 | 1500 | 0 | 1650 | 0 | 1 | 1 |
| 21 | 22 | 120000 | 2 | 2 | 1 | 39 | -1 | -1 | -1 | -1 | ... | 632 | 316 | 316 | 316 | 0 | 632 | 316 | 0 | 1 | 1 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 46723 | 9494 | 30000 | 1 | 1 | 2 | 34 | 0 | 0 | 2 | 2 | ... | 24647 | 25223 | 4395 | 407 | 1521 | 0 | 986 | 1651 | 1 | 1 |
| 46724 | 7761 | 360000 | 2 | 1 | 1 | 42 | 1 | -2 | -2 | -2 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| 46725 | 14562 | 100000 | 2 | 2 | 2 | 28 | 0 | 0 | 2 | 0 | ... | 99914 | 98462 | 8468 | 168 | 3348 | 6624 | 259 | 3045 | 1 | 1 |
| 46726 | 11928 | 30000 | 1 | 1 | 2 | 35 | 0 | 0 | 2 | 0 | ... | 8577 | 0 | 2507 | 0 | 374 | 5424 | 0 | 0 | 1 | 1 |
| 46727 | 14200 | 258678 | 1 | 1 | 1 | 38 | 2 | 0 | 0 | 2 | ... | 96678 | 97688 | 6910 | 6904 | 278 | 3112 | 3085 | 3099 | 1 | 1 |
23364 rows × 26 columns
from imblearn.over_sampling import SMOTE, ADASYN, BorderlineSMOTE
from imblearn.combine import SMOTEENN
from sklearn.metrics import mean_squared_error
# Liste des techniques de suréchantillonnage
oversamplers = {
'SMOTE': SMOTE(),
'ADASYN': ADASYN(),
'Borderline-SMOTE': BorderlineSMOTE(),
'SMOTE-ENN': SMOTEENN(),
}
# Mesurer les statistiques avant le suréchantillonnage
before_stats = df.groupby('IsDefaulter').size()
# Appliquer les techniques de suréchantillonnage
after_stats = {}
for name, oversampler in oversamplers.items():
X_resampled, y_resampled = oversampler.fit_resample(X, y)
after_stats[name] = pd.Series(y_resampled).value_counts()
# Afficher les différences avant et après le suréchantillonnage
print("Statistiques avant le suréchantillonnage:\n", before_stats)
print("\nStatistiques après le suréchantillonnage:")
for name, stats in after_stats.items():
print(name, ":\n", stats)
# Mesurer la différence entre les moyennes des classes
print("\nDifférence entre les moyennes des classes avant et après le suréchantillonnage:")
for name, stats in after_stats.items():
diff_mean = abs(stats[0] / stats.sum() - before_stats[0] / before_stats.sum())
print(name, ":", diff_mean)
Statistiques avant le suréchantillonnage: IsDefaulter 0 23364 1 6636 dtype: int64 Statistiques après le suréchantillonnage: SMOTE : 1 23364 0 23364 Name: IsDefaulter, dtype: int64 ADASYN : 1 24085 0 23364 Name: IsDefaulter, dtype: int64 Borderline-SMOTE : 1 23364 0 23364 Name: IsDefaulter, dtype: int64 SMOTE-ENN : 1 17426 0 10010 Name: IsDefaulter, dtype: int64 Différence entre les moyennes des classes avant et après le suréchantillonnage: SMOTE : 0.27880000000000005 ADASYN : 0.28639763114080385 Borderline-SMOTE : 0.27880000000000005 SMOTE-ENN : 0.41395089663216217
from imblearn.over_sampling import SMOTE, ADASYN, BorderlineSMOTE
from imblearn.combine import SMOTEENN
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import make_scorer, accuracy_score
# Supposons que 'X' est votre jeu de données et 'y' est votre variable cible
X = df.drop("IsDefaulter", axis=1)
y= df["IsDefaulter"]
# Liste des techniques d'oversampling
sampling_techniques = [
('SMOTE', SMOTE()),
('ADASYN', ADASYN()),
('Borderline-SMOTE', BorderlineSMOTE()),
('SMOTE-ENN', SMOTEENN())
]
# Modèle de classification (par exemple, Logistic Regression)
model = LogisticRegression()
# Métrique de performance
scoring = make_scorer(accuracy_score)
# Boucle à travers les techniques d'oversampling
for name, technique in sampling_techniques:
X_resampled, y_resampled = technique.fit_resample(X, y)
# Évaluer les performances en utilisant la validation croisée
scores = cross_val_score(model, X_resampled, y_resampled, cv=5, scoring=scoring)
# Afficher les résultats
print(f'Technique: {name}')
#print(X_resampled?shape)
print(f'Mean Accuracy: {scores.mean()}')
print(f'Standard Deviation: {scores.std()}')
print('---')
Technique: SMOTE Mean Accuracy: 0.5645625948824097 Standard Deviation: 0.0559878890000623 --- Technique: ADASYN Mean Accuracy: 0.567092938071158 Standard Deviation: 0.028008367722404656 --- Technique: Borderline-SMOTE Mean Accuracy: 0.578836520535018 Standard Deviation: 0.05927169056618682 --- Technique: SMOTE-ENN Mean Accuracy: 0.697990609977457 Standard Deviation: 0.06297818538487025 ---
# Appliquer SMOTE pour le suréchantillonnage
smote = SMOTE(sampling_strategy=0.5) # Ajustez la stratégie de suréchantillonnage si nécessaire
X_resampled, y_resampled = smote.fit_resample(X, y)
# Créer un nouveau DataFrame avec les données suréchantillonnées
smote_sampled_df = pd.concat([X_resampled, y_resampled], axis=1)
from scipy.stats import ks_2samp
# Avant le suréchantillonnage
before_oversampling = df['IsDefaulter']
# Après le suréchantillonnage (par exemple, SMOTE)
after_oversampling = smote_sampled_df['IsDefaulter']#['feature_of_interest']
#Par exemple, si vous souhaitez évaluer l'impact du suréchantillonnage sur la variable "âge", vous remplaceriez
#"feature_of_interest" par "âge". Voici comment cela ressemblerait dans le code :
#before_oversampling = df[df['target'] == 'minority']['âge']
# Calcul de la statistique de KS
ks_statistic, p_value = ks_2samp(before_oversampling, after_oversampling)
print("Statistique de KS:", ks_statistic)
print("Valeur P:", p_value)
# Calcul de la proportion de la classe minoritaire après suréchantillonnage
before_oversampling = len(before_oversampling) / len(df[df['IsDefaulter']==1])
after_oversampling = len(after_oversampling) / len(smote_sampled_df[smote_sampled_df['IsDefaulter']==1])
print("Proportion avant suréchantillonnage:", before_oversampling)
print("Proportion après suréchantillonnage:", after_oversampling)
# Visualisation des distributions
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 5))
plt.hist(before_oversampling, bins=30, alpha=0.5, label='Avant suréchantillonnage')
plt.hist(after_oversampling, bins=30, alpha=0.5, label='Après suréchantillonnage')
plt.xlabel('Feature of Interest')
plt.ylabel('Fréquence')
plt.legend()
plt.show()
Statistique de KS: 0.11213333333333342 Valeur P: 1.7319599438844477e-177 Proportion avant suréchantillonnage: 4.520795660036167 Proportion après suréchantillonnage: 3.0
#2. **Proportion de la classe minoritaire après le suréchantillonnage**:
# Avant suréchantillonnage
before_minority_proportion = df['IsDefaulter'].sum() / len(df)
# Après suréchantillonnage (par exemple, SMOTE)
after_minority_proportion = smote_sampled_df['IsDefaulter'].sum() / len(smote_sampled_df)
print("Proportion avant suréchantillonnage:", before_minority_proportion)
print("Proportion après suréchantillonnage:", after_minority_proportion)
Proportion avant suréchantillonnage: 0.2212 Proportion après suréchantillonnage: 0.3333333333333333
df_fr = balance_df.copy()
balance_df.columns
Index(['ID', 'LIMIT_BAL', 'SEX', 'EDUCATION', 'MARRIAGE', 'AGE', 'PAY_SEPT',
'PAY_AUG', 'PAY_JUL', 'PAY_JUN', 'PAY_MAY', 'PAY_APR', 'BILL_AMT_SEPT',
'BILL_AMT_AUG', 'BILL_AMT_JUL', 'BILL_AMT_JUN', 'BILL_AMT_MAY',
'BILL_AMT_APR', 'PAY_AMT_SEPT', 'PAY_AMT_AUG', 'PAY_AMT_JUL',
'PAY_AMT_JUN', 'PAY_AMT_MAY', 'PAY_AMT_APR',
'default.payment.next.month', 'IsDefaulter'],
dtype='object')
df_fr
| ID | LIMIT_BAL | SEX | EDUCATION | MARRIAGE | AGE | PAY_SEPT | PAY_AUG | PAY_JUL | PAY_JUN | ... | BILL_AMT_MAY | BILL_AMT_APR | PAY_AMT_SEPT | PAY_AMT_AUG | PAY_AMT_JUL | PAY_AMT_JUN | PAY_AMT_MAY | PAY_AMT_APR | default.payment.next.month | IsDefaulter | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 20000 | 2 | 2 | 1 | 24 | 2 | 2 | -1 | -1 | ... | 0 | 0 | 0 | 689 | 0 | 0 | 0 | 0 | 1 | 1 |
| 1 | 2 | 120000 | 2 | 2 | 2 | 26 | -1 | 2 | 0 | 0 | ... | 3455 | 3261 | 0 | 1000 | 1000 | 1000 | 0 | 2000 | 1 | 1 |
| 2 | 3 | 90000 | 2 | 2 | 2 | 34 | 0 | 0 | 0 | 0 | ... | 14948 | 15549 | 1518 | 1500 | 1000 | 1000 | 1000 | 5000 | 0 | 0 |
| 3 | 4 | 50000 | 2 | 2 | 1 | 37 | 0 | 0 | 0 | 0 | ... | 28959 | 29547 | 2000 | 2019 | 1200 | 1100 | 1069 | 1000 | 0 | 0 |
| 4 | 5 | 50000 | 1 | 2 | 1 | 57 | -1 | 0 | -1 | 0 | ... | 19146 | 19131 | 2000 | 36681 | 10000 | 9000 | 689 | 679 | 0 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 46723 | 9494 | 30000 | 1 | 1 | 2 | 34 | 0 | 0 | 2 | 2 | ... | 24647 | 25223 | 4395 | 407 | 1521 | 0 | 986 | 1651 | 1 | 1 |
| 46724 | 7761 | 360000 | 2 | 1 | 1 | 42 | 1 | -2 | -2 | -2 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| 46725 | 14562 | 100000 | 2 | 2 | 2 | 28 | 0 | 0 | 2 | 0 | ... | 99914 | 98462 | 8468 | 168 | 3348 | 6624 | 259 | 3045 | 1 | 1 |
| 46726 | 11928 | 30000 | 1 | 1 | 2 | 35 | 0 | 0 | 2 | 0 | ... | 8577 | 0 | 2507 | 0 | 374 | 5424 | 0 | 0 | 1 | 1 |
| 46727 | 14200 | 258678 | 1 | 1 | 1 | 38 | 2 | 0 | 0 | 2 | ... | 96678 | 97688 | 6910 | 6904 | 278 | 3112 | 3085 | 3099 | 1 | 1 |
46728 rows × 26 columns
df_fr['Payement_Value'] = df_fr['PAY_SEPT'] + df_fr['PAY_AUG'] + df_fr['PAY_JUL'] + df_fr['PAY_JUN'] + df_fr['PAY_MAY'] \
+ df_fr['PAY_APR']
df_fr.groupby('IsDefaulter')['Payement_Value'].mean()
IsDefaulter 0 -1.980140 1 1.701507 Name: Payement_Value, dtype: float64
plt.figure(figsize=(10,10))
sns.boxplot(data = df_fr, x = 'IsDefaulter', y = 'Payement_Value',showmeans=True)
<AxesSubplot:xlabel='IsDefaulter', ylabel='Payement_Value'>
df.columns
Index(['ID', 'LIMIT_BAL', 'SEX', 'EDUCATION', 'MARRIAGE', 'AGE', 'PAY_SEPT',
'PAY_AUG', 'PAY_JUL', 'PAY_JUN', 'PAY_MAY', 'PAY_APR', 'BILL_AMT_SEPT',
'BILL_AMT_AUG', 'BILL_AMT_JUL', 'BILL_AMT_JUN', 'BILL_AMT_MAY',
'BILL_AMT_APR', 'PAY_AMT_SEPT', 'PAY_AMT_AUG', 'PAY_AMT_JUL',
'PAY_AMT_JUN', 'PAY_AMT_MAY', 'PAY_AMT_APR',
'default.payment.next.month', 'IsDefaulter'],
dtype='object')
sorts=df_fr['Payement_Value'].sort_values()
sorts
23363 -12
1757 -12
15479 -12
35526 -12
22186 -12
..
13635 33
8997 33
25869 33
18867 33
8654 36
Name: Payement_Value, Length: 46728, dtype: int32
q1=sorts.quantile(0.25)
q3=sorts.quantile(0.75)
print("The value of q1 is:",q1)
print("The value of q3 is:",q3)
The value of q1 is: -4.0 The value of q3 is: 2.0
q1=sorts.quantile(0.25)
q3=sorts.quantile(0.75)
print("The value of q1 is:",q1)
print("The value of q3 is:",q3)
The value of q1 is: -4.0 The value of q3 is: 2.0
iqr = q3 - q1
print("The value of iqr is:",iqr)
The value of iqr is: 6.0
upper=q1-1.5*iqr
lower=q3+1.5*iqr
print("The value of upper bound is:",round(upper))
print("The value of lower bound is:",round(lower))
The value of upper bound is: -13 The value of lower bound is: 11
clean_data=sorts[~((sorts<(upper)) | (sorts>(lower)))]
clean_data
23363 -12
1757 -12
15479 -12
35526 -12
22186 -12
..
44334 11
32075 11
43962 11
40603 11
10338 11
Name: Payement_Value, Length: 44773, dtype: int32
sns.boxplot(data=df_fr,x='Payement_Value',showmeans=True)
plt.show()
sns.boxplot(x=clean_data,showmeans=True)
plt.show()
var = ['BILL_AMT_SEPT',
'BILL_AMT_AUG', 'BILL_AMT_JUL', 'BILL_AMT_JUN', 'BILL_AMT_MAY',
'BILL_AMT_APR']
plt.figure(figsize = (8,8))
plt.title('Amount of bill statement (Apr-Sept) \ncorrelation plot (Pearson)')
corr = df[var].corr()
sns.heatmap(corr,xticklabels=corr.columns,yticklabels=corr.columns,linewidths=.1,vmin=-1, vmax=1)
plt.show()
class_0 = df.loc[df['default.payment.next.month'] == 0]["LIMIT_BAL"]
class_1 = df.loc[df['default.payment.next.month'] == 1]["LIMIT_BAL"]
plt.figure(figsize = (14,6))
plt.title('Default amount of credit limit - grouped by Payment Next Month (Density Plot)')
sns.set_color_codes("pastel")
sns.distplot(class_1,kde=True,bins=200, color="red")
sns.distplot(class_0,kde=True,bins=200, color="green")
plt.show()
df.columns
Index(['ID', 'LIMIT_BAL', 'SEX', 'EDUCATION', 'MARRIAGE', 'AGE', 'PAY_SEPT',
'PAY_AUG', 'PAY_JUL', 'PAY_JUN', 'PAY_MAY', 'PAY_APR', 'BILL_AMT_SEPT',
'BILL_AMT_AUG', 'BILL_AMT_JUL', 'BILL_AMT_JUN', 'BILL_AMT_MAY',
'BILL_AMT_APR', 'PAY_AMT_SEPT', 'PAY_AMT_AUG', 'PAY_AMT_JUL',
'PAY_AMT_JUN', 'PAY_AMT_MAY', 'PAY_AMT_APR',
'default.payment.next.month', 'IsDefaulter'],
dtype='object')
gender = df.groupby(['SEX', 'IsDefaulter']).size().unstack(1)
# 1 is the default for unstack, but I put it to show explicitly what we are unstacking
gender
| IsDefaulter | 0 | 1 |
|---|---|---|
| SEX | ||
| 1 | 9015 | 2873 |
| 2 | 14349 | 3763 |
import seaborn as sns
import matplotlib.pyplot as plt
# Example predictor variables and target variable
predictor_var1 = [2, 4, 6, 8, 10]
predictor_var2 = [1, 3, 5, 7, 9]
categorical_target = ['A', 'B', 'A', 'B', 'A']
# Create a DataFrame with the variables
data = pd.DataFrame({'Predictor_Var1': predictor_var1,
'Predictor_Var2': predictor_var2,
'Categorical_Target': categorical_target})
# Create a boxplot using seaborn
sns.boxplot(x='Categorical_Target', y='Predictor_Var1', data=data)
plt.show()
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# Example predictor variables and target variable
predictor_vars = {
'Predictor_Var1': [2, 4, 6, 8, 10],
'Predictor_Var2': [1, 3, 5, 7, 9],
'Predictor_Var3': [0, 2, 4, 6, 8]
}
categorical_target = ['A', 'B', 'A', 'B', 'A']
# Create a DataFrame with the variables
data = pd.DataFrame(predictor_vars)
data['Categorical_Target'] = categorical_target
# Create boxplots for each predictor variable
for var in predictor_vars:
plt.figure()
sns.boxplot(x='Categorical_Target', y=var, data=data,showmeans=True)
plt.title(var)
plt.show()
import pandas as pd
from scipy.stats import chi2_contingency
# Exemple de jeu de données avec des variables catégorielles
data = pd.DataFrame({'Caractéristique1': ['A', 'B', 'A', 'B', 'A'],
'Caractéristique2': ['X', 'Y', 'X', 'Y', 'X'],
'Cible': [1, 0, 1, 0, 1]})
# Créer une table de contingence
table_contingence = pd.crosstab(data['Caractéristique1'], data['Caractéristique2'])
# Effectuer le test du chi2
chi2, p_value, _, _ = chi2_contingency(table_contingence)
# Afficher les résultats
print("Valeur du chi2 :", chi2)
print("Valeur p :", p_value)
Valeur du chi2 : 1.7013888888888888 Valeur p : 0.1921064408679386
import pandas as pd
# Exemple de données
data = {
'colonne_a_modifier': ['123', '4567', '89', '987654321', '12']
}
# Charger les données dans un DataFrame
df = pd.DataFrame(data)
# Fonction pour ajouter des zéros
def ajouter_zeros(valeur):
zeros_a_ajouter = 9 - len(valeur)
return '0' * zeros_a_ajouter + valeur
# Appliquer la fonction sur la colonne spécifiée
colonne_a_modifier = 'colonne_a_modifier'
df[colonne_a_modifier] = df[colonne_a_modifier].apply(ajouter_zeros)
# Afficher le résultat
print(df)
colonne_a_modifier 0 000000123 1 000004567 2 000000089 3 987654321 4 000000012
import pandas as pd
# Exemple de données avec une colonne "ma_colonne" contenant des valeurs
data = {
"ma_colonne": [123, 4567, 89, 12345678, 98765432]
}
# Création du DataFrame à partir des données
df = pd.DataFrame(data)
# Fonction pour ajouter des zéros à gauche jusqu'à atteindre une taille de 9
def ajouter_zeros(valeur):
return str(valeur).zfill(9)
# Appliquer la fonction "ajouter_zeros" à la colonne "ma_colonne"
df["ma_colonne"] = df["ma_colonne"].apply(ajouter_zeros)
# Afficher le DataFrame après avoir ajouté des zéros
print(df)
ma_colonne 0 000000123 1 000004567 2 000000089 3 012345678 4 098765432
# Example string
my_string = "Hello"
# Add spaces to the right until the string reaches a length of 10
padded_string = my_string.rjust(10,'0')
print(padded_string) # Output: "Hello "
00000Hello
import pandas as pd
import numpy as np
# Générer des données aléatoires
np.random.seed(42)
n_samples = 1000
data = {
'id': range(1, n_samples + 1),
'date_arrete': pd.date_range(start='2020-01-01', periods=n_samples, freq='M'),
'annee': np.random.randint(2020, 2023, size=n_samples),
'mois': np.random.randint(1, 13, size=n_samples),
'age': np.random.randint(20, 70, size=n_samples),
'anciennete_bancaire_mois': np.random.randint(6, 240, size=n_samples),
'situation_matrimoniale': np.random.choice(['Célibataire', 'Marié', 'Divorcé', 'Veuf'], size=n_samples),
'solde_fin_mois': np.random.uniform(-5000, 50000, size=n_samples),
'nb_pret': np.random.randint(0, 5, size=n_samples),
'cumul_crediteur': np.random.uniform(0, 100000, size=n_samples),
'cumul_debiteur': np.random.uniform(0, 100000, size=n_samples),
'salaire': np.random.uniform(1000, 10000, size=n_samples),
'mtn_paiement_par_carte': np.random.uniform(0, 5000, size=n_samples),
'nb_paiement_par_carte': np.random.randint(0, 50, size=n_samples),
'nb_virement': np.random.randint(0, 20, size=n_samples),
'mnt_virement': np.random.uniform(0, 20000, size=n_samples),
'nb_versement': np.random.randint(0, 10, size=n_samples),
'mtn_versement': np.random.uniform(0, 10000, size=n_samples),
'mtn_paye': np.random.uniform(0, 10000, size=n_samples),
'mtn_impaye': np.random.uniform(0, 10000, size=n_samples),
'target': np.random.choice([0, 1], size=n_samples, p=[0.8, 0.2])
}
# Créer le DataFrame
df = pd.DataFrame(data)
print(df.shape)
# Afficher les premières lignes du DataFrame
df.head()
(1000, 21)
| id | date_arrete | annee | mois | age | anciennete_bancaire_mois | situation_matrimoniale | solde_fin_mois | nb_pret | cumul_crediteur | ... | salaire | mtn_paiement_par_carte | nb_paiement_par_carte | nb_virement | mnt_virement | nb_versement | mtn_versement | mtn_paye | mtn_impaye | target | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2020-01-31 | 2022 | 7 | 56 | 52 | Célibataire | 3954.827732 | 1 | 76944.257942 | ... | 5294.317384 | 1149.591854 | 32 | 15 | 5235.057381 | 9 | 8444.056123 | 9535.722238 | 6268.536213 | 0 |
| 1 | 2 | 2020-02-29 | 2020 | 3 | 51 | 83 | Veuf | 5280.294233 | 4 | 93479.551749 | ... | 2177.930247 | 2579.729393 | 32 | 9 | 10251.818505 | 0 | 4532.997386 | 8396.244959 | 736.182615 | 0 |
| 2 | 3 | 2020-03-31 | 2022 | 3 | 60 | 129 | Veuf | -3911.238791 | 3 | 90920.213621 | ... | 3120.093411 | 1267.468766 | 43 | 16 | 6612.016199 | 0 | 7264.413581 | 4260.008105 | 1896.963649 | 0 |
| 3 | 4 | 2020-04-30 | 2022 | 8 | 22 | 80 | Divorcé | 16487.516104 | 4 | 81962.486955 | ... | 9392.535578 | 4702.686506 | 19 | 0 | 17210.229732 | 6 | 955.362076 | 6447.168378 | 3378.538857 | 0 |
| 4 | 5 | 2020-05-31 | 2020 | 5 | 47 | 108 | Divorcé | 5528.522427 | 2 | 88819.134966 | ... | 8735.526781 | 4529.719840 | 46 | 17 | 9475.203075 | 2 | 3960.243463 | 1770.709219 | 778.700643 | 0 |
5 rows × 21 columns
anciennete_bancaire_mois = Chaque valeur représente le nombre de mois pendant lesquels un individu a été client de la banque
Voici le dictionnaire de données pour les variables que vous avez mentionnées :
** Spécifiez la population ou le groupe sur lequel portera votre étude. Si vous étudiez un sous-ensemble de la population (échantillon), expliquez comment vous sélectionnerez les participants.
** Indiquez toute limitation géographique ou temporelle. Par exemple, vous pourriez vous concentrer sur une région ou une période spécifique.
** Mentionnez brièvement les méthodes de recherche que vous utiliserez pour collecter et analyser les données. S'agira-t-il de méthodes qualitatives, quantitatives ou de méthodes mixtes ?
** Soyez clair sur ce que vous ne couvrirez pas dans votre étude. Cela évite le débordement du champ d'étude et maintient la concentration sur vos objectifs principaux.
** Décrivez ce que vous avez l'intention de produire en résultat de votre étude. Il peut s'agir d'un rapport, d'une analyse, de recommandations ou d'autres résultats.
** Reconnaissez les prémisses que vous faites et les limitations qui pourraient affecter les résultats de l'étude.
est d'élaborer un modèle de scoring comportemental basé sur des données financières et comportementales des clients. Les principaux objectifs de cette étude sont les suivants :
Développer un Modèle de Scoring : Concevoir et construire un modèle prédictif qui évalue le comportement financier des clients et attribue un score en fonction de leurs antécédents de paiement, d'endettement, de dépenses et d'autres facteurs pertinents.
Évaluer le Risque de Défaut : L'objectif principal du scoring comportemental est d'évaluer le risque de défaut d'un individu ou d'une entité. Cela implique de développer un modèle qui peut prédire avec précision la probabilité qu'un emprunteur ou un client ne parvienne pas à rembourser ses dettes.
Identifer les Facteurs de Risque : Examiner les variables et les caractéristiques qui ont un impact significatif sur le comportement de remboursement. Cela peut inclure des variables telles que l'historique de paiement, le montant des dettes, l'ancienneté bancaire, etc.
Optimiser les Décisions de Crédit : Utiliser les scores comportementaux pour prendre des décisions éclairées en matière de crédit. Les scores peuvent aider les prêteurs à déterminer les limites de crédit appropriées, à évaluer la solvabilité et à personnaliser les offres de produits financiers.
Améliorer la Gestion des Risques : Fournir aux institutions financières un outil pour gérer efficacement les risques associés aux prêts et aux crédits. Cela peut conduire à des politiques de prêt plus ciblées et à une réduction des pertes.
Suivre les Comportements Financiers : Suivre l'évolution des comportements de paiement des clients au fil du temps. Cela peut aider à détecter les signes précoces de difficultés financières et à prendre des mesures correctives.
Personnalisation des Offres : Utiliser les scores comportementaux pour personnaliser les offres et les services financiers en fonction du profil et des habitudes de paiement de chaque individu.
Améliorer la Rentabilité : En réduisant les risques de défaut et en prenant des décisions plus précises en matière de crédit, les institutions financières peuvent améliorer leur rentabilité globale.
Validation et Ajustements du Modèle : Les objectifs incluent la validation et l'ajustement constants du modèle de scoring pour garantir sa précision et sa pertinence dans un environnement financier en évolution.
---------------boxplot pour voir la reartitions des données, taux de missing, considerer que les tzrget detecter
Q1 (premier quartile) : Le premier quartile divise les données en deux parties égales, où 25% des valeurs se situent en dessous de Q1. Cela signifie que 25% des données sont inférieures à Q1.
Q2 (deuxième quartile) : Q2 est simplement une autre appellation pour la médiane. Il divise les données en deux parties égales, où 50% des valeurs se situent en dessous de Q2 et 50% des valeurs se situent au-dessus de Q2.
Q3 (troisième quartile) : Le troisième quartile divise les données en deux parties égales, où 75% des valeurs se situent en dessous de Q3. Cela signifie que 25% des données sont supérieures à Q3
from IPython.display import Image
Image(filename='img.jpg')
# Grouper les données par la variable cible 'target'
grouped = df.groupby('target')
# Comparer les moyennes des variables numériques pour les deux groupes
numeric_vars = ['age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement', 'mnt_virement', 'nb_versement',
'mtn_versement', 'mtn_paye', 'mtn_impaye']
plt.figure(figsize=(15, 10))
for var in numeric_vars:
plt.subplot(4, 4, numeric_vars.index(var) + 1)
sns.boxplot(data=df, x='target', y=var,showmeans=True)
plt.title(var)
plt.tight_layout()
plt.show()
# Variables numériques que vous souhaitez analyser
numeric_variables = ['age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'salaire']
# Boucle pour créer des histogrammes pour chaque variable numérique
for variable in numeric_variables:
plt.figure(figsize=(10, 6))
# Histogramme pour les clients en défaut (target = 1)
plt.hist(df[df['target'] == 1][variable], bins=20, color='red', alpha=0.5, label='Défaut (1)')
# Histogramme pour les clients non en défaut (target = 0)
plt.hist(df[df['target'] == 0][variable], bins=20, color='blue', alpha=0.5, label='Pas en Défaut (0)')
plt.title(f'Distribution de {variable} en fonction du Target')
plt.xlabel(variable)
plt.ylabel('Fréquence')
plt.legend()
plt.grid(True)
plt.show()
import seaborn as sns
import matplotlib.pyplot as plt
# Séparer les données en fonction du target
df_target_0 = df[df['target'] == 0]
df_target_1 = df[df['target'] == 1]
# Liste des colonnes numériques à visualiser
numeric_columns = ['age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'cumul_crediteur', 'cumul_debiteur', 'salaire', 'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement', 'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye', 'mtn_impaye']
# Ajuster la taille du graphique
plt.figure(figsize=(30, 15))
# Tracer les courbes de densité de probabilité pour chaque variable numérique
for col in numeric_columns:
plt.subplot(4, 4, numeric_columns.index(col) + 1) # Créer une grille 4x4 de sous-graphiques
sns.kdeplot(data=df_target_0[col], label='Non Défaut (0)', shade=True)
sns.kdeplot(data=df_target_1[col], label='Défaut (1)', shade=True)
plt.title(col)
plt.xlabel('')
plt.ylabel('Densité')
plt.legend()
# Ajuster l'espacement entre les sous-graphiques
plt.tight_layout()
# Afficher le graphique
plt.show()
df.columns
Index(['id', 'date_arrete', 'annee', 'mois', 'age', 'anciennete_bancaire_mois',
'situation_matrimoniale', 'solde_fin_mois', 'nb_pret',
'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement',
'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye',
'mtn_impaye', 'target', 'anciennete_bancaire_range', 'dettes_cumulees',
'paiement_anormaux', 'salaire_range', 'age_group', 'constante'],
dtype='object')
import pandas as pd
# Charger le DataFrame depuis le code que vous avez fourni
# Assurez-vous que le DataFrame 'df' est déjà créé
# Grouper par année et target, puis calculer les statistiques
grouped_stats = df.groupby(['annee', 'target'])[['cumul_crediteur', 'cumul_debiteur', 'solde_fin_mois', 'salaire']].describe()
# Afficher les statistiques
grouped_stats
| cumul_crediteur | cumul_debiteur | ... | solde_fin_mois | salaire | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | mean | std | min | 25% | 50% | 75% | max | count | mean | ... | 75% | max | count | mean | std | min | 25% | 50% | 75% | max | ||
| annee | target | |||||||||||||||||||||
| 2020 | 0 | 10.0 | 60315.049538 | 29259.192734 | 19921.968584 | 31505.656129 | 65699.895204 | 87104.972963 | 93479.551749 | 10.0 | 44480.163809 | ... | 18420.046223 | 46424.693751 | 10.0 | 5976.076397 | 2745.892826 | 2177.930247 | 3663.649404 | 5511.469854 | 8398.661448 | 9691.933995 |
| 1 | 2.0 | 26846.684718 | 15356.532663 | 15987.976337 | 21417.330528 | 26846.684718 | 32276.038909 | 37705.393100 | 2.0 | 53489.980237 | ... | 36109.863440 | 43289.147334 | 2.0 | 9038.570957 | 1044.580366 | 8299.941097 | 8669.256027 | 9038.570957 | 9407.885887 | 9777.200818 | |
| 2021 | 0 | 12.0 | 45292.131517 | 24051.312095 | 8744.650180 | 27462.299640 | 45843.083045 | 65696.243325 | 79644.056152 | 12.0 | 58438.033623 | ... | 38007.930677 | 49012.724536 | 12.0 | 5491.658173 | 2790.446199 | 1801.087614 | 2885.173975 | 5124.370327 | 7597.883717 | 9383.899664 |
| 2022 | 0 | 9.0 | 32191.769939 | 32781.744437 | 3981.143945 | 10868.253937 | 17909.493933 | 39221.779343 | 95564.946727 | 9.0 | 48227.588614 | ... | 48740.732818 | 49469.898010 | 9.0 | 5350.240096 | 3388.186533 | 1645.618094 | 2434.553963 | 5039.662291 | 9184.992976 | 9712.199548 |
| 1 | 3.0 | 75124.645335 | 34548.672821 | 35232.705425 | 65005.337611 | 94777.969797 | 95070.615290 | 95363.260783 | 3.0 | 14979.273329 | ... | 46040.097988 | 46769.984653 | 3.0 | 3113.171707 | 1429.491544 | 2090.399151 | 2296.475381 | 2502.551611 | 3624.557984 | 4746.564357 | |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 2101 | 1 | 4.0 | 51578.167060 | 39272.706928 | 13574.585310 | 23281.451916 | 46401.526441 | 74698.241584 | 99935.030047 | 4.0 | 73539.594378 | ... | 10905.896644 | 12465.501893 | 4.0 | 4891.369035 | 3599.727571 | 1219.518938 | 2535.292443 | 4457.138166 | 6813.214758 | 9431.680871 |
| 2102 | 0 | 9.0 | 50631.868072 | 34701.808267 | 8839.696715 | 27171.759890 | 34222.552478 | 81595.578942 | 98138.333424 | 9.0 | 40720.993768 | ... | 36749.781291 | 45094.146903 | 9.0 | 4774.412869 | 3085.254252 | 1340.381229 | 3102.223908 | 3371.261011 | 7475.139709 | 9877.149306 |
| 1 | 3.0 | 29821.051703 | 17256.175426 | 10015.499751 | 23923.530234 | 37831.560717 | 39723.827679 | 41616.094641 | 3.0 | 28675.429423 | ... | 30208.018952 | 35014.107662 | 3.0 | 1777.788179 | 511.800724 | 1188.185611 | 1612.947712 | 2037.709813 | 2072.589463 | 2107.469112 | |
| 2103 | 0 | 3.0 | 65785.477335 | 43344.788587 | 16653.851350 | 49369.376138 | 82084.900926 | 90351.290327 | 98617.679728 | 3.0 | 27962.971434 | ... | 26394.581561 | 35364.795735 | 3.0 | 2149.001938 | 773.088850 | 1508.641217 | 1719.597823 | 1930.554430 | 2469.182298 | 3007.810166 |
| 1 | 1.0 | 28147.730245 | NaN | 28147.730245 | 28147.730245 | 28147.730245 | 28147.730245 | 28147.730245 | 1.0 | 79554.439193 | ... | 1906.106825 | 1906.106825 | 1.0 | 4883.573079 | NaN | 4883.573079 | 4883.573079 | 4883.573079 | 4883.573079 | 4883.573079 | |
162 rows × 32 columns
import pandas as pd
# Charger le DataFrame depuis le code que vous avez fourni
# Assurez-vous que le DataFrame 'df' est déjà créé
# Sélectionner les colonnes d'intérêt
columns_of_interest = ['annee', 'cumul_crediteur', 'cumul_debiteur', 'mtn_paye', 'target']
# Filtrer les clients ayant des valeurs non nulles pour les cumuls créditeurs, débiteurs et montants payés
filtered_df = df[df['cumul_crediteur'] > 0.0]
filtered_df = filtered_df[filtered_df['cumul_debiteur'] > 0.0]
filtered_df = filtered_df[filtered_df['mtn_paye'] > 0.0]
# Grouper par année, target et compter le nombre de clients
grouped_counts = filtered_df.groupby(['annee', 'target']).size().reset_index(name='nombre_de_clients')
# Afficher les résultats
grouped_counts
| annee | target | nombre_de_clients | |
|---|---|---|---|
| 0 | 2020 | 0 | 10 |
| 1 | 2020 | 1 | 2 |
| 2 | 2021 | 0 | 12 |
| 3 | 2022 | 0 | 9 |
| 4 | 2022 | 1 | 3 |
| ... | ... | ... | ... |
| 157 | 2101 | 1 | 4 |
| 158 | 2102 | 0 | 9 |
| 159 | 2102 | 1 | 3 |
| 160 | 2103 | 0 | 3 |
| 161 | 2103 | 1 | 1 |
162 rows × 3 columns
# Créer un tableau croisé dynamique pour le nombre de clients par année et target
pivot_table = pd.pivot_table(df, values='id', index='annee', columns='target', aggfunc='count', fill_value=0)
# Renommer les colonnes du tableau
pivot_table.columns = ['Non Défaut (0)', 'Défaut (1)']
# Afficher le tableau
pivot_table
| Non Défaut (0) | Défaut (1) | |
|---|---|---|
| annee | ||
| 2020 | 10 | 2 |
| 2021 | 12 | 0 |
| 2022 | 9 | 3 |
| 2023 | 11 | 1 |
| 2024 | 12 | 0 |
| ... | ... | ... |
| 2099 | 9 | 3 |
| 2100 | 10 | 2 |
| 2101 | 8 | 4 |
| 2102 | 9 | 3 |
| 2103 | 3 | 1 |
84 rows × 2 columns
df.columns
Index(['id', 'date_arrete', 'annee', 'mois', 'age', 'anciennete_bancaire_mois',
'situation_matrimoniale', 'solde_fin_mois', 'nb_pret',
'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement',
'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye',
'mtn_impaye', 'target', 'anciennete_bancaire_range', 'dettes_cumulees',
'paiement_anormaux', 'salaire_range', 'age_group', 'constante'],
dtype='object')
import pandas as pd
# Supposons que votre DataFrame s'appelle 'df'
# Regrouper les données par année et par target, puis calculer la somme des montants cumulés dans chaque groupe
total_cumul_by_year = df.groupby(['annee', 'target'])['cumul_crediteur'].sum().reset_index()
# Renommer la colonne 'cumul_crediteur' en 'montant_total_cumul'
total_cumul_by_year.rename(columns={'cumul_crediteur': 'montant_total_cumul'}, inplace=True)
total_cumul_by_year
| annee | target | montant_total_cumul | |
|---|---|---|---|
| 0 | 2020 | 0 | 603150.495384 |
| 1 | 2020 | 1 | 53693.369437 |
| 2 | 2021 | 0 | 543505.578206 |
| 3 | 2022 | 0 | 289725.929447 |
| 4 | 2022 | 1 | 225373.936005 |
| ... | ... | ... | ... |
| 157 | 2101 | 1 | 206312.668239 |
| 158 | 2102 | 0 | 455686.812646 |
| 159 | 2102 | 1 | 89463.155108 |
| 160 | 2103 | 0 | 197356.432004 |
| 161 | 2103 | 1 | 28147.730245 |
162 rows × 3 columns
# Supposons que votre DataFrame s'appelle 'df'
data = df[df.annee.isin([2020, 2021, 2022, 2023])]
# Calculer le nombre total de clients par année et par target
total_clients_by_year = data.groupby(['annee', 'target'])['cumul_crediteur'].count().unstack()
# Définir un style esthétique avec Seaborn
sns.set_style("whitegrid")
sns.set_palette("Set2")
# Créer un graphique en barres pour le nombre total de clients par année et target
plt.figure(figsize=(10, 6))
total_clients_by_year.plot(kind='bar', stacked=True)
plt.title("Nombre Total de Clients par Année et Target")
plt.xlabel("Année")
plt.ylabel("Nombre Total de Clients")
plt.legend(title='Target', labels=['Non Défaut (0)', 'Défaut (1)'])
plt.xticks(rotation=45) # Rotation des étiquettes pour une meilleure lisibilité
plt.tight_layout() # Ajuster la disposition pour éviter la superposition
plt.show()
<Figure size 720x432 with 0 Axes>
# Regrouper les données par année et par target, puis calculer la somme des montants cumulés dans chaque groupe
grouped_data = data.groupby(['annee', 'target']).agg({
'cumul_crediteur': 'sum',
'mtn_paye': 'sum',
'mtn_impaye': 'sum',
'mnt_virement': 'sum',
# Ajoutez d'autres colonnes si nécessaire
}).reset_index()
# Renommer les colonnes pour une meilleure lisibilité
grouped_data.rename(columns={
'cumul_crediteur': 'Montant Total Cumulé',
'mtn_paye': 'Montant Payé',
'mtn_impaye': 'Montant Impayé',
'mnt_virement': 'Montant Virement',
# Ajoutez d'autres renommages de colonnes si nécessaire
}, inplace=True)
grouped_data
| annee | target | Montant Total Cumulé | Montant Payé | Montant Impayé | Montant Virement | |
|---|---|---|---|---|---|---|
| 0 | 2020 | 0 | 603150.495384 | 65073.306289 | 34852.180604 | 113969.874566 |
| 1 | 2020 | 1 | 53693.369437 | 15068.583344 | 12421.236445 | 17575.435891 |
| 2 | 2021 | 0 | 543505.578206 | 52487.103545 | 81360.849807 | 103705.814461 |
| 3 | 2022 | 0 | 289725.929447 | 57687.575657 | 48920.996739 | 108465.728662 |
| 4 | 2022 | 1 | 225373.936005 | 20287.244474 | 9023.106442 | 35387.837379 |
| 5 | 2023 | 0 | 670564.042057 | 57087.396730 | 45482.269067 | 109889.847172 |
| 6 | 2023 | 1 | 91764.727790 | 3429.351158 | 7477.652771 | 1772.659495 |
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Supposons que votre DataFrame s'appelle 'df'
# Regrouper les données par année et par target, puis calculer la somme des montants dans chaque groupe
grouped_data = data.groupby(['annee', 'target']).agg({
'cumul_crediteur': 'sum',
'mtn_paye': 'sum',
'mtn_impaye': 'sum',
'mnt_virement': 'sum'
}).reset_index()
# Définir un style esthétique avec Seaborn
sns.set_style("whitegrid")
sns.set_palette("Set2")
# Créer des sous-plots pour chaque montant en fonction du target et de l'année
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
fig.suptitle("Sommes des Montants en Fonction du Target et de l'Année")
# Montant Total Cumulé
sns.barplot(data=grouped_data, x='annee', y='cumul_crediteur', hue='target', ax=axes[0, 0])
axes[0, 0].set_title("Montant Total Cumulé")
axes[0, 0].set_xlabel("Année")
axes[0, 0].set_ylabel("Montant")
# Montant Payé
sns.barplot(data=grouped_data, x='annee', y='mtn_paye', hue='target', ax=axes[0, 1])
axes[0, 1].set_title("Montant Payé")
axes[0, 1].set_xlabel("Année")
axes[0, 1].set_ylabel("Montant")
# Montant Impayé
sns.barplot(data=grouped_data, x='annee', y='mtn_impaye', hue='target', ax=axes[1, 0])
axes[1, 0].set_title("Montant Impayé")
axes[1, 0].set_xlabel("Année")
axes[1, 0].set_ylabel("Montant")
# Montant de Virement
sns.barplot(data=grouped_data, x='annee', y='mnt_virement', hue='target', ax=axes[1, 1])
axes[1, 1].set_title("Montant de Virement")
axes[1, 1].set_xlabel("Année")
axes[1, 1].set_ylabel("Montant")
# Ajuster l'espacement entre les sous-plots
plt.tight_layout()
plt.subplots_adjust(top=0.9)
# Afficher les graphiques
plt.show()
import pandas as pd
# Supposons que votre DataFrame s'appelle 'df'
# Créer une nouvelle colonne pour les classes de situation matrimoniale
def categorize_marital_status(status):
if status in ['Divorcé', 'Veuf']:
return 'Divorcé/Veuf'
elif status == 'Célibataire':
return 'Célibataire'
elif status == 'Marié':
return 'Marié'
else:
return 'Autre' # Vous pouvez gérer d'autres valeurs si nécessaire
data['marital_status_group'] = data['situation_matrimoniale'].apply(categorize_marital_status)
# Regrouper les données par année, par classe de situation matrimoniale et par target, puis compter le nombre de clients dans chaque groupe
grouped_data = df.groupby(['annee', 'marital_status_group', 'target'])['id'].count().unstack().reset_index()
grouped_data
| target | annee | marital_status_group | 0 | 1 |
|---|---|---|---|---|
| 0 | 2020 | Célibataire | 2.0 | 1.0 |
| 1 | 2020 | Divorcé/Veuf | 7.0 | NaN |
| 2 | 2020 | Marié | 1.0 | 1.0 |
| 3 | 2021 | Célibataire | 2.0 | NaN |
| 4 | 2021 | Divorcé/Veuf | 6.0 | NaN |
| 5 | 2021 | Marié | 4.0 | NaN |
| 6 | 2022 | Célibataire | NaN | 2.0 |
| 7 | 2022 | Divorcé/Veuf | 6.0 | NaN |
| 8 | 2022 | Marié | 3.0 | 1.0 |
| 9 | 2023 | Célibataire | 2.0 | NaN |
| 10 | 2023 | Divorcé/Veuf | 6.0 | NaN |
| 11 | 2023 | Marié | 3.0 | 1.0 |
df.situation_matrimoniale.unique()
array(['Divorcé', 'Célibataire', 'Marié', 'Veuf'], dtype=object)
Quel est l'effet des montants des dettes cumulées sur la capacité à rembourser les crédits ? L'effet des montants de dettes cumulées sur la capacité à rembourser les crédits peut avoir des implications significatives pour la solvabilité d'un individu. En termes simples, cela se réfère à la question de savoir comment le total des dettes qu'une personne a accumulées peut influencer sa capacité à honorer ses engagements financiers, tels que les remboursements de crédits. Imaginons un scénario où un individu a accumulé un montant élevé de dettes provenant de différents prêts, cartes de crédit ou autres obligations financières. Plus ce montant de dettes cumulées est élevé, plus il peut y avoir de pression sur les ressources financières de cette personne
Dans quelle mesure les comportements de paiement passés peuvent-ils prédire les comportements futurs en matière de crédit ?
XxxxXxxxLes habitudes de paiement par carte (montant et fréquence) sont-elles liées à la performance de remboursement ?
Comment les comportements financiers varient-ils en fonction de l'âge des emprunteurs ?
Célibataire (Single): Le taux de défaut moyen pour les personnes célibataires est d'environ 20.91%. Cela signifie que parmi les emprunteurs célibataires, environ 20.91% ont tendance à ne pas rembourser leurs crédits en temps voulu.
Divorcé (Divorced): Les emprunteurs divorcés ont un taux de défaut moyen d'environ 20.65%. Cela indique qu'environ 20.65% des personnes divorcées ont des difficultés à honorer leurs obligations de paiement.
Marié (Married): Les personnes mariées ont un taux de défaut moyen d'environ 21.37%. Cela implique que près de 21.37% des emprunteurs mariés ne remboursent pas leurs crédits de manière adéquate.
Veuf (Widowed): Les emprunteurs veufs affichent un taux de défaut moyen d'environ 19.14%. Cela suggère que 19.14% des personnes veuves connaissent des problèmes de remboursement.
En interprétant ces résultats, on peut dire qu'il y a des différences légères entre les taux de défaut moyens pour différents groupes d'état matrimonial. Cependant, les variations ne semblent pas être très prononcées. En substance, les taux de défaut ne varient pas considérablement en fonction de l'état matrimonial des emprunteurs dans cet ensemble de données. Cela suggère que l'état matrimonial seul pourrait ne pas être un facteur majeur dans la prédiction des comportements de remboursement, du moins dans le contexte de cette analyse.
# Grouper les données par état matrimonial et calculer le taux de défaut moyen
grouped = df.groupby('situation_matrimoniale')['target'].mean().reset_index()
# Créer un graphique pour visualiser les variations avec les taux de défaut affichés sur les barres
plt.figure(figsize=(10, 6))
bars = plt.bar(grouped['situation_matrimoniale'], grouped['target'], color='skyblue')
plt.title('Taux de Défaut par État Matrimonial')
plt.xlabel('État Matrimonial')
plt.ylabel('Taux de Défaut')
plt.xticks(rotation=45)
plt.tight_layout()
# Afficher les taux de défaut au-dessus des barres
for bar in bars:
yval = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2, yval, round(yval, 2), ha='center', va='bottom', fontsize=10)
plt.show()
# Créer un graphique de dispersion et une ligne de régression pour visualiser la corrélation
plt.figure(figsize=(10, 6))
sns.regplot(x='anciennete_bancaire_mois', y='target', data=df)#, logistic=True)
plt.xlabel("Ancienneté Bancaire (mois)")
plt.ylabel("Probabilité de Défaut")
plt.title("Corrélation entre Ancienneté Bancaire et Probabilité de Défaut")
plt.show()
# Calculer la corrélation entre les deux variables
correlation = df['anciennete_bancaire_mois'].corr(df['target'])
print(f"Corrélation entre Ancienneté Bancaire et Probabilité de Défaut : {correlation:.4f}")
Corrélation entre Ancienneté Bancaire et Probabilité de Défaut : 0.0355
df['anciennete_bancaire_range'] = pd.cut(df['anciennete_bancaire_mois'], bins=3)
default_by_seniority = df.groupby('anciennete_bancaire_range')['target'].mean()
plt.figure(figsize=(10, 6))
bar_plot = default_by_seniority.plot(kind='bar', color='green', alpha=0.7)
plt.xlabel('Tranche d\'Ancienneté Bancaire')
plt.ylabel('Probabilité de Défaut Moyenne')
plt.title('Probabilité de Défaut Moyenne par Tranche d\'Ancienneté Bancaire')
plt.xticks(rotation=45)
# Ajouter les annotations des probabilités moyennes sur les barres
for index, value in enumerate(default_by_seniority):
bar_plot.annotate(f'{value:.2f}', xy=(index, value), ha='center', va='bottom')
plt.show()
# Supposons que votre DataFrame a une colonne 'target' (1 pour défaut, 0 pour non-défaut)
data_defaut = df[df['target'] == 1]
data_non_defaut = df[df['target'] == 0]
# Analyse des paiements par carte au fil du temps pour chaque groupe
paiements_defaut = data_defaut.groupby('annee')['solde_fin_mois'].sum()
paiements_non_defaut = data_non_defaut.groupby('annee')['solde_fin_mois'].sum()
# Créez le graphique de ligne comparatif
plt.figure(figsize=(10, 6))
plt.plot(paiements_defaut.index, paiements_defaut.values, label='En Défaut')
plt.plot(paiements_non_defaut.index, paiements_non_defaut.values, label='Non en Défaut')
plt.xlabel('Année')
plt.ylabel('Montant solde_fin_mois')
plt.title('Comparaison des solde_fin_mois au Fil des Années')
plt.legend()
plt.grid(True)
plt.show()
# Supposons que votre DataFrame a une colonne 'target' (1 pour défaut, 0 pour non-défaut)
data_defaut = df[df['target'] == 1]
data_non_defaut = df[df['target'] == 0]
# Calculez la somme des paiements par carte pour chaque année et chaque groupe
paiements_defaut = data_defaut.groupby(['annee'])['mtn_paye'].sum()
paiements_non_defaut = data_non_defaut.groupby(['annee'])['mtn_paye'].sum()
# Créez le graphique à barres comparatif
plt.figure(figsize=(10, 6))
width = 0.35
plt.bar(paiements_defaut.index, paiements_defaut.values, width, label='En Défaut')
plt.bar(paiements_non_defaut.index + width, paiements_non_defaut.values, width, label='Non en Défaut')
plt.xlabel('Année')
plt.ylabel('Montant Total des Paiements par Carte')
plt.title('Comparaison des Paiements')
plt.xticks(paiements_defaut.index + width / 2, paiements_defaut.index)
plt.legend()
plt.grid(True)
plt.show()
import pandas as pd
import matplotlib.pyplot as plt
# Supposons que vous avez un DataFrame df avec une colonne 'annee' et une colonne 'mnt_paiement_par_carte'
data=df[df.annee.isin([2020,2021,2022,2023])]
# Regroupez les données par année et calculez la somme des paiements par carte pour chaque année
soldes_par_annee = data.groupby('annee')['solde_fin_mois'].sum()
# Créez le graphique en barres
plt.figure(figsize=(10, 6))
soldes_par_annee.plot(kind='bar', color='blue')
# Ajoutez des labels et un titre
plt.xlabel('Année')
plt.ylabel('Montant Total des Paiements par Carte')
plt.title('Évolution des Paiements par Carte au Fil des Années (Graphique en Barres)')
# Afficher les valeurs numériques au-dessus de chaque barre
for index, value in enumerate(soldes_par_annee):
plt.text(index, value, f"{value:.2f}", ha='center', va='bottom')
# Affichez le graphique
plt.show()
# Calculez le montant total de paiements par carte, virements et versements pour chaque année et chaque groupe
montant_paiement_par_carte_defaut = df[df['target'] == 1].groupby('annee')['mtn_paiement_par_carte'].sum()
montant_paiement_par_carte_non_defaut = df[df['target'] == 0].groupby('annee')['mtn_paiement_par_carte'].sum()
montant_virement_defaut = df[df['target'] == 1].groupby('annee')['mnt_virement'].sum()
montant_virement_non_defaut = df[df['target'] == 0].groupby('annee')['mnt_virement'].sum()
montant_versement_defaut = df[df['target'] == 1].groupby('annee')['mtn_versement'].sum()
montant_versement_non_defaut = df[df['target'] == 0].groupby('annee')['mtn_versement'].sum()
# Créez les graphiques en barres groupées
fig, axes = plt.subplots(3, 1, figsize=(10, 18))
def create_grouped_bar_chart(ax, data1, data2, label1, label2, ylabel):
width = 0.35
x = data1.index
ax.bar(x, data1, width, label=label1)
ax.bar(x, data2, width, bottom=data1, label=label2)
ax.set_ylabel(ylabel)
ax.set_title(f'Évolution des Montants par Année et Statut de Défaut')
ax.set_xticks(x)
ax.set_xticklabels(data1.index)
ax.legend()
ax.grid(True)
create_grouped_bar_chart(axes[0], montant_paiement_par_carte_defaut, montant_paiement_par_carte_non_defaut, 'En Défaut', 'Non en Défaut', 'Montant Paiement par Carte')
create_grouped_bar_chart(axes[1], montant_virement_defaut, montant_virement_non_defaut, 'En Défaut', 'Non en Défaut', 'Montant Virement')
create_grouped_bar_chart(axes[2], montant_versement_defaut, montant_versement_non_defaut, 'En Défaut', 'Non en Défaut', 'Montant Versement')
# Afficher les valeurs sur les barres
for ax in axes:
for p in ax.patches:
ax.annotate(f'{int(p.get_height()):,}', (p.get_x() + p.get_width() / 2., p.get_height()),
ha='center', va='center', fontsize=10, color='black', xytext=(0, 5),
textcoords='offset points')
plt.tight_layout()
plt.show()
# Créer un graphique de dispersion et une ligne de régression pour visualiser la corrélation
plt.figure(figsize=(10, 6))
sns.regplot(x='mtn_impaye', y='target', data=df)#, logistic=True)
plt.xlabel("mtn_paye")
plt.ylabel("Probabilité de Défaut")
plt.title("Corrélation entre Ancienneté Bancaire et Probabilité de Défaut")
plt.show()
# Calculer la corrélation entre les deux variables
correlation = df['anciennete_bancaire_mois'].corr(df['target'])
print(f"Corrélation entre mtn_impaye et Probabilité de Défaut : {correlation:.4f}")
Corrélation entre mtn_impaye et Probabilité de Défaut : 0.0355
# Créer un graphique de dispersion et une ligne de régression pour visualiser la corrélation
plt.figure(figsize=(10, 6))
sns.regplot(x='mtn_paye', y='target', data=df)#, logistic=True)
plt.xlabel("mtn_paye")
plt.ylabel("Probabilité de Défaut")
plt.title("Corrélation entre Ancienneté Bancaire et Probabilité de Défaut")
plt.show()
# Calculer la corrélation entre les deux variables
correlation = df['anciennete_bancaire_mois'].corr(df['target'])
print(f"Corrélation entre mtn_paye et Probabilité de Défaut : {correlation:.4f}")
Corrélation entre mtn_paye et Probabilité de Défaut : 0.0355
Q1 (premier quartile) : Le premier quartile divise les données en deux parties égales, où 25% des valeurs se situent en dessous de Q1. Cela signifie que 25% des données sont inférieures à Q1.
Q2 (deuxième quartile) : Q2 est simplement une autre appellation pour la médiane. Il divise les données en deux parties égales, où 50% des valeurs se situent en dessous de Q2 et 50% des valeurs se situent au-dessus de Q2.
Q3 (troisième quartile) : Le troisième quartile divise les données en deux parties égales, où 75% des valeurs se situent en dessous de Q3. Cela signifie que 25% des données sont supérieures à Q3
from IPython.display import Image
Image(filename='img.jpg')
# Grouper les données par la variable cible 'target'
grouped = df.groupby('target')
# Comparer les moyennes des variables numériques pour les deux groupes
numeric_vars = ['age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement', 'mnt_virement', 'nb_versement',
'mtn_versement', 'mtn_paye', 'mtn_impaye']
plt.figure(figsize=(15, 10))
for var in numeric_vars:
plt.subplot(4, 4, numeric_vars.index(var) + 1)
sns.boxplot(data=df, x='target', y=var,showmeans=True)
plt.title(var)
plt.tight_layout()
plt.show()
# Comparer les proportions des catégories de la variable 'situation_matrimoniale' pour les deux groupes
plt.figure(figsize=(8, 6))
sns.countplot(data=df, x='situation_matrimoniale', hue='target')
plt.title('Répartition par Situation Matrimoniale')
plt.legend(title='Défaut')
plt.show()
df['salaire_range'] = pd.cut(df['salaire'], bins=2)
default_by_seniority = df.groupby('salaire_range')['target'].mean()
plt.figure(figsize=(10, 6))
bar_plot = default_by_seniority.plot(kind='bar', color='green', alpha=0.7)
plt.xlabel('Tranche de salaire_range')
plt.ylabel('Probabilité de Défaut Moyenne')
plt.title('Probabilité de Défaut Moyenne par Tranche de salaire_range')
plt.xticks(rotation=45)
# Ajouter les annotations des probabilités moyennes sur les barres
for index, value in enumerate(default_by_seniority):
bar_plot.annotate(f'{value:.2f}', xy=(index, value), ha='center', va='bottom')
plt.show()
import pandas as pd
import matplotlib.pyplot as plt
# Chargement du DataFrame (vous pouvez remplacer cette partie par votre propre DataFrame)
# df = ...
# Définition des classes d'âge
age_bins = [20, 30, 40, 50, 60, 70]
age_labels = ['20-29', '30-39', '40-49', '50-59', '60-69']
# Ajout d'une colonne pour la classe d'âge
df['age_group'] = pd.cut(df['age'], bins=age_bins, labels=age_labels, right=False)
# Calcul des agrégats en fonction de la classe d'âge
age_group_means = df.groupby('age_group').agg({
'cumul_crediteur': 'mean', # Montant moyen cumulé créditeur
'cumul_debiteur': 'mean', # Montant moyen cumulé débiteur
'salaire': 'mean', # Salaire moyen
'mtn_paiement_par_carte': 'mean', # Montant moyen paiement par carte
'target': 'mean' # Taux de Défaut moyen
}).reset_index()
# Création du graphique
plt.figure(figsize=(10, 6))
plt.plot(age_group_means['age_group'], age_group_means['cumul_crediteur'], label='Cumul Créditeur', marker='o')
plt.plot(age_group_means['age_group'], age_group_means['cumul_debiteur'], label='Cumul Débiteur', marker='s')
plt.plot(age_group_means['age_group'], age_group_means['salaire'], label='Salaire', marker='^')
plt.plot(age_group_means['age_group'], age_group_means['mtn_paiement_par_carte'], label='Montant Paiement par Carte', marker='D')
plt.plot(age_group_means['age_group'], age_group_means['target'], label='Taux de Défaut', marker='v')
plt.xlabel('Classe d\'Âge')
plt.ylabel('Valeurs Moyennes')
plt.title('Comportements Financiers en Fonction de la Classe d\'Âge')
plt.legend()
plt.grid(True)
plt.show()
data=df[df.annee.isin([2020,2021,2022,2023])]
# Calculer la fréquence des défauts par mois
defauts_par_mois = data.groupby(['annee', 'mois'])['target'].mean()
# Créer un graphique
plt.figure(figsize=(10, 6))
defauts_par_mois.plot(marker='o')
plt.title("Taux de Défauts de Paiement par Mois")
plt.xlabel("Mois")
plt.ylabel("Taux de Défauts")
plt.xticks(rotation=45)
plt.grid(True)
plt.tight_layout()
plt.show()
import pandas as pd
import matplotlib.pyplot as plt
# Agrégation des données par mois et calcul du taux de défaut
monthly_defaults = df.groupby('mois')['target'].mean()
# Création du graphique
plt.figure(figsize=(10, 6))
plt.plot(monthly_defaults.index, monthly_defaults.values, marker='o')
plt.title("Taux de Défaut de Paiement en Fonction des Mois")
plt.xlabel("Mois")
plt.ylabel("Taux de Défaut de Paiement")
plt.xticks(range(1, 13), ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc'])
plt.grid(True)
plt.show()
data=df[df.annee.isin([2020,2021,2022])]
# Agrégation des données par année et mois et calcul du taux de défaut
yearly_monthly_defaults = data.groupby(['annee', 'mois'])['target'].mean().reset_index()
# Création du graphique
plt.figure(figsize=(12, 6))
# Utilisation d'une boucle pour itérer à travers chaque année
for year in sorted(yearly_monthly_defaults['annee'].unique()):
data_year = yearly_monthly_defaults[yearly_monthly_defaults['annee'] == year]
plt.plot(data_year['mois'], data_year['target'], marker='o', label=str(year))
plt.title("Taux de Défaut de Paiement en Fonction des Mois et des Années")
plt.xlabel("Mois")
plt.ylabel("Taux de Défaut de Paiement")
plt.xticks(range(1, 13), ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc'])
plt.legend(title='Année')
plt.grid(True)
plt.show()
data=df[df.annee.isin([2020,2021,2022])]
# Agrégation des données par mois et calcul du taux de défaut
monthly_defaults = data.groupby('annee')['target'].mean()
# Création du graphique
plt.figure(figsize=(10, 6))
plt.plot(monthly_defaults.index, monthly_defaults.values, marker='o')
plt.title("Taux de Défaut de Paiement en Fonction des anees")
plt.xlabel("annee")
plt.ylabel("Taux de Défaut de Paiement")
plt.xticks(range(1, 4), ['2020', '2021', '2022'])
plt.grid(True)
plt.show()
import pandas as pd
import statsmodels.api as sm
# Charger le DataFrame depuis le code que vous avez fourni
# Assurez-vous que le DataFrame 'df' est déjà créé
# Sélectionner les variables indépendantes (caractéristiques) pour la modélisation
features = ['age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'nb_pret', 'cumul_crediteur', 'cumul_debiteur', 'salaire', 'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement', 'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye', 'mtn_impaye']
# Ajouter une constante à la matrice de caractéristiques (interception)
X = sm.add_constant(df[features])
# Variable cible (target)
y = df['target']
# Créer le modèle de régression logistique
model = sm.Logit(y, X)
# Ajuster le modèle aux données
results = model.fit()
# Afficher les résultats de la régression logistique
print(results.summary())
Optimization terminated successfully.
Current function value: 0.493913
Iterations 5
Logit Regression Results
==============================================================================
Dep. Variable: target No. Observations: 1000
Model: Logit Df Residuals: 984
Method: MLE Df Model: 15
Date: Sun, 13 Aug 2023 Pseudo R-squ.: 0.01022
Time: 13:34:53 Log-Likelihood: -493.91
converged: True LL-Null: -499.01
Covariance Type: nonrobust LLR p-value: 0.8070
============================================================================================
coef std err z P>|z| [0.025 0.975]
--------------------------------------------------------------------------------------------
const -1.0247 0.572 -1.793 0.073 -2.145 0.096
age -0.0031 0.006 -0.562 0.574 -0.014 0.008
anciennete_bancaire_mois 0.0015 0.001 1.186 0.236 -0.001 0.004
solde_fin_mois 1.419e-06 5.15e-06 0.276 0.783 -8.68e-06 1.15e-05
nb_pret -0.0234 0.057 -0.409 0.683 -0.136 0.089
cumul_crediteur -1.878e-06 2.8e-06 -0.670 0.503 -7.37e-06 3.62e-06
cumul_debiteur -3.521e-07 2.78e-06 -0.126 0.899 -5.81e-06 5.1e-06
salaire 1.665e-05 3.1e-05 0.538 0.591 -4.4e-05 7.73e-05
mtn_paiement_par_carte -2.094e-05 5.67e-05 -0.369 0.712 -0.000 9.03e-05
nb_paiement_par_carte -0.0020 0.006 -0.362 0.717 -0.013 0.009
nb_virement -0.0117 0.014 -0.842 0.400 -0.039 0.016
mnt_virement 3.672e-06 1.41e-05 0.261 0.794 -2.39e-05 3.12e-05
nb_versement 0.0273 0.028 0.977 0.329 -0.027 0.082
mtn_versement 2.4e-07 2.79e-05 0.009 0.993 -5.44e-05 5.49e-05
mtn_paye -2.934e-06 2.75e-05 -0.107 0.915 -5.67e-05 5.09e-05
mtn_impaye -6.348e-05 2.79e-05 -2.274 0.023 -0.000 -8.78e-06
============================================================================================
df.columns
Index(['id', 'date_arrete', 'annee', 'mois', 'age', 'anciennete_bancaire_mois',
'situation_matrimoniale', 'solde_fin_mois', 'nb_pret',
'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement',
'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye',
'mtn_impaye', 'target', 'anciennete_bancaire_range', 'dettes_cumulees',
'paiement_anormaux', 'salaire_range', 'age_group', 'constante'],
dtype='object')
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Charger le DataFrame depuis le code que vous avez fourni
# Assurez-vous que le DataFrame 'df' est déjà créé
# Caractéristiques à comparer
features_to_compare = ['age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'nb_pret', 'cumul_crediteur', 'cumul_debiteur', 'salaire', 'mtn_paiement_par_carte']
# Comparaison de distributions
plt.figure(figsize=(15, 10))
for feature in features_to_compare:
plt.subplot(3, 3, features_to_compare.index(feature) + 1)
sns.boxplot(x='target', y=feature, data=df)
plt.title(f'{feature} par Target')
plt.ylabel(feature)
plt.tight_layout()
plt.show()
df.situation_matrimoniale
779 Divorcé
186 Célibataire
255 Célibataire
856 Marié
348 Célibataire
...
549 Célibataire
207 Célibataire
388 Marié
903 Célibataire
928 Veuf
Name: situation_matrimoniale, Length: 1000, dtype: string
df.situation_matrimoniale = df.situation_matrimoniale.astype('string')
import pandas as pd
data.situation_matrimoniale = data.situation_matrimoniale.astype('string')
# Découper une colonne catégorielle en classes
num_bins = 3 # Nombre de classes souhaitées
colonne_categorique = 'situation_matrimoniale' # Remplacez par le nom de votre colonne
# Découper la colonne en classes
df['colonne_classes'] = pd.cut(data[colonne_categorique], bins=num_bins, labels=False)
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [458], in <cell line: 3>() 1 import pandas as pd ----> 3 data.situation_matrimoniale = data.situation_matrimoniale.astype('string') 5 # Découper une colonne catégorielle en classes 6 num_bins = 3 # Nombre de classes souhaitées AttributeError: 'dict' object has no attribute 'situation_matrimoniale'
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# Supposons que votre DataFrame s'appelle 'df'
# Fonction pour découper une variable numérique en classes
def discretize_variable(data, variable, bins):
labels = [f'Bin {i}' for i in range(1, len(bins))]
data[f'{variable}_bin'] = pd.cut(data[variable], bins=bins, labels=labels)
return data
# Découper une variable numérique en classes (par exemple, 'age')
bins = [20, 30, 40, 50, 60, 70]
df = discretize_variable(df, 'age', bins)
# Calculer le taux de risque pour chaque classe
risk_rates = df.groupby('age_bin')['target'].mean().reset_index()
risk_rates.rename(columns={'target': 'Risk Rate'}, inplace=True)
# Calculer l'information value pour chaque classe
def calculate_iv(data, variable_bin):
obs = pd.crosstab(data[variable_bin], data['target'])
chi2, p, dof, expected = chi2_contingency(obs)
iv = np.sum((obs / np.sum(obs)) * np.log((obs / np.sum(obs)) / (expected / np.sum(expected))))
return iv
iv_values = []
for bin_label in df['age_bin'].unique():
iv = calculate_iv(df[df['age_bin'] == bin_label], 'age_bin')
iv_values.append({'age_bin': bin_label, 'IV': iv})
iv_df = pd.DataFrame(iv_values)
# Afficher le taux de risque et les valeurs d'IV
print(risk_rates)
print(iv_df)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [457], in <cell line: 29>() 28 iv_values = [] 29 for bin_label in df['age_bin'].unique(): ---> 30 iv = calculate_iv(df[df['age_bin'] == bin_label], 'age_bin') 31 iv_values.append({'age_bin': bin_label, 'IV': iv}) 33 iv_df = pd.DataFrame(iv_values) Input In [457], in calculate_iv(data, variable_bin) 22 def calculate_iv(data, variable_bin): 23 obs = pd.crosstab(data[variable_bin], data['target']) ---> 24 chi2, p, dof, expected = chi2_contingency(obs) 25 iv = np.sum((obs / np.sum(obs)) * np.log((obs / np.sum(obs)) / (expected / np.sum(expected)))) 26 return iv File ~\anaconda3\lib\site-packages\scipy\stats\contingency.py:269, in chi2_contingency(observed, correction, lambda_) 267 raise ValueError("All values in `observed` must be nonnegative.") 268 if observed.size == 0: --> 269 raise ValueError("No data; `observed` has size 0.") 271 expected = expected_freq(observed) 272 if np.any(expected == 0): 273 # Include one of the positions where expected is zero in 274 # the exception message. ValueError: No data; `observed` has size 0.
# Calculer le taux de risque pour chaque classe
risk_rates = df.groupby('age_bin')['target'].mean().reset_index()
risk_rates.rename(columns={'target': 'Risk Rate'}, inplace=True)
# Définir un seuil pour les occurrences minimales
min_occurrences = 10
# Regrouper les classes adjacentes avec un nombre d'occurrences faible
def merge_low_occurrence_bins(data, variable_bin, min_occurrences):
bin_occurrences = data[variable_bin].value_counts()
bins_to_merge = bin_occurrences[bin_occurrences < min_occurrences].index
data[variable_bin] = data[variable_bin].replace(bins_to_merge, 'Autre')
return data
df = merge_low_occurrence_bins(df, 'age_bin', min_occurrences)
# Calculer l'information value pour chaque classe
iv_values = []
for bin_label in df['age_bin'].unique():
iv = calculate_iv(df[df['age_bin'] == bin_label], 'age_bin')
iv_values.append({'age_bin': bin_label, 'IV': iv})
iv_df = pd.DataFrame(iv_values)
# Afficher le taux de risque et les valeurs d'IV
print(risk_rates)
print(iv_df)
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Input In [456], in <cell line: 2>() 1 # Calculer le taux de risque pour chaque classe ----> 2 risk_rates = df.groupby('age_bin')['target'].mean().reset_index() 3 risk_rates.rename(columns={'target': 'Risk Rate'}, inplace=True) 5 # Définir un seuil pour les occurrences minimales File ~\anaconda3\lib\site-packages\pandas\core\frame.py:7712, in DataFrame.groupby(self, by, axis, level, as_index, sort, group_keys, squeeze, observed, dropna) 7707 axis = self._get_axis_number(axis) 7709 # https://github.com/python/mypy/issues/7642 7710 # error: Argument "squeeze" to "DataFrameGroupBy" has incompatible type 7711 # "Union[bool, NoDefault]"; expected "bool" -> 7712 return DataFrameGroupBy( 7713 obj=self, 7714 keys=by, 7715 axis=axis, 7716 level=level, 7717 as_index=as_index, 7718 sort=sort, 7719 group_keys=group_keys, 7720 squeeze=squeeze, # type: ignore[arg-type] 7721 observed=observed, 7722 dropna=dropna, 7723 ) File ~\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py:882, in GroupBy.__init__(self, obj, keys, axis, level, grouper, exclusions, selection, as_index, sort, group_keys, squeeze, observed, mutated, dropna) 879 if grouper is None: 880 from pandas.core.groupby.grouper import get_grouper --> 882 grouper, exclusions, obj = get_grouper( 883 obj, 884 keys, 885 axis=axis, 886 level=level, 887 sort=sort, 888 observed=observed, 889 mutated=self.mutated, 890 dropna=self.dropna, 891 ) 893 self.obj = obj 894 self.axis = obj._get_axis_number(axis) File ~\anaconda3\lib\site-packages\pandas\core\groupby\grouper.py:882, in get_grouper(obj, key, axis, level, sort, observed, mutated, validate, dropna) 880 in_axis, level, gpr = False, gpr, None 881 else: --> 882 raise KeyError(gpr) 883 elif isinstance(gpr, Grouper) and gpr.key is not None: 884 # Add key to exclusions 885 exclusions.add(gpr.key) KeyError: 'age_bin'
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2_contingency
# Créer le DataFrame
np.random.seed(42)
n_samples = 1000
data = {
'id': range(1, n_samples + 1),
'date_arrete': pd.date_range(start='2020-01-01', periods=n_samples, freq='M'),
'annee': np.random.randint(2020, 2023, size=n_samples),
'mois': np.random.randint(1, 13, size=n_samples),
'age': np.random.randint(20, 70, size=n_samples),
'anciennete_bancaire_mois': np.random.randint(6, 240, size=n_samples),
'situation_matrimoniale': np.random.choice(['Célibataire', 'Marié', 'Divorcé', 'Veuf'], size=n_samples),
'solde_fin_mois': np.random.uniform(-5000, 50000, size=n_samples),
'nb_pret': np.random.randint(0, 5, size=n_samples),
'cumul_crediteur': np.random.uniform(0, 100000, size=n_samples),
'cumul_debiteur': np.random.uniform(0, 100000, size=n_samples),
'salaire': np.random.uniform(1000, 10000, size=n_samples),
'mtn_paiement_par_carte': np.random.uniform(0, 5000, size=n_samples),
'nb_paiement_par_carte': np.random.randint(0, 50, size=n_samples),
'nb_virement': np.random.randint(0, 20, size=n_samples),
'mnt_virement': np.random.uniform(0, 20000, size=n_samples),
'nb_versement': np.random.randint(0, 10, size=n_samples),
'mtn_versement': np.random.uniform(0, 10000, size=n_samples),
'mtn_paye': np.random.uniform(0, 10000, size=n_samples),
'mtn_impaye': np.random.uniform(0, 10000, size=n_samples),
'target': np.random.choice([0, 1], size=n_samples, p=[0.8, 0.2])
}
df = pd.DataFrame(data)
# = []
for i in range(len(bins) - 1):
bin_range = (bins[i], bins[i+1])
total_obs, iv = calculate_iv(df, 'mnt_virement', 'target', bin_range)
iv_values.append(iv)
total_observations.append(total_obs)
# Afficher les informations sur un graphique bar
plt.figure(figsize=(12, 6))
plt.bar([f'Bin {i}' for i in range(1, len(bins))], iv_values)
plt.xlabel('Classe de Bin')
plt.ylabel('Information Value (IV)')
plt.title('Information Value (IV) pour la variable mnt_virement')
plt.xticks(rotation=45)
plt.twinx()
plt.plot([f'Bin {i}' for i in range(1, len(bins))], total_observations, color='orange', marker='o', linestyle='dashed')
plt.ylabel('Nombre total d\'observations')
plt.tight_layout()
plt.show()
mnt_virement_bin Risk Rate 0 Bin 1 0.183036 1 Bin 2 0.193676 2 Bin 3 0.208413 mnt_virement_bin IV 0 Bin 2 target 0 0.215269 1 1.641569 dtype: float64 1 Bin 3 target 0 0.233715 1 1.568234 dtype: float64 2 Bin 1 target 0 0.202160 1 1.698074 dtype: float64
bins = [0, 3000, 6000, 9000, 12000]
labels = ['Faible', 'Moyen', 'Élevé', 'Très élevé']
data['salaire_categorie'] = pd.cut(data['salaire'], bins=bins, labels=labels)
data['salaire_categorie']
['Moyen', 'Faible', 'Moyen', 'Très élevé', 'Élevé', ..., 'Faible', 'Moyen', 'Faible', 'Faible', 'Moyen'] Length: 1000 Categories (4, object): ['Faible' < 'Moyen' < 'Élevé' < 'Très élevé']
data['salaire_categorie']
['Moyen', 'Faible', 'Moyen', 'Très élevé', 'Élevé', ..., 'Faible', 'Moyen', 'Faible', 'Faible', 'Moyen'] Length: 1000 Categories (4, object): ['Faible' < 'Moyen' < 'Élevé' < 'Très élevé']
data['salaire_categoriea'] = pd.factorize(data['salaire_categorie'])[0]
data['salaire_categoriea']
array([0, 1, 0, 2, 3, 3, 0, 0, 2, 2, 1, 3, 1, 1, 3, 0, 2, 1, 0, 2, 2, 1,
0, 3, 1, 2, 2, 1, 1, 1, 2, 1, 0, 0, 3, 1, 0, 2, 2, 3, 1, 0, 3, 0,
2, 3, 1, 2, 2, 1, 0, 0, 0, 1, 3, 2, 0, 1, 3, 0, 3, 0, 1, 1, 3, 0,
3, 1, 0, 0, 2, 2, 1, 0, 1, 0, 0, 2, 2, 0, 0, 2, 3, 1, 0, 0, 0, 1,
1, 3, 0, 1, 0, 3, 3, 0, 0, 2, 1, 1, 0, 1, 0, 2, 3, 0, 2, 1, 1, 3,
3, 1, 0, 3, 3, 3, 0, 1, 0, 1, 2, 0, 0, 3, 0, 0, 3, 3, 3, 1, 3, 3,
1, 0, 3, 1, 3, 0, 0, 1, 3, 0, 0, 3, 3, 2, 0, 0, 2, 3, 0, 1, 3, 0,
3, 0, 1, 3, 1, 0, 0, 0, 3, 3, 3, 1, 1, 0, 2, 3, 3, 0, 0, 0, 1, 1,
2, 0, 0, 1, 2, 3, 3, 2, 0, 3, 1, 1, 3, 3, 0, 0, 0, 1, 0, 1, 0, 3,
0, 1, 0, 3, 0, 1, 0, 3, 0, 3, 2, 3, 3, 0, 1, 2, 0, 1, 3, 0, 3, 3,
0, 3, 0, 0, 0, 3, 3, 0, 3, 1, 2, 0, 3, 1, 1, 0, 3, 0, 2, 0, 0, 1,
3, 0, 2, 2, 2, 0, 3, 3, 1, 3, 1, 0, 1, 1, 0, 0, 3, 1, 0, 1, 3, 3,
3, 3, 0, 3, 0, 0, 3, 1, 3, 3, 0, 1, 1, 2, 3, 1, 0, 3, 3, 1, 0, 2,
1, 1, 2, 3, 0, 1, 1, 0, 3, 0, 3, 2, 0, 1, 0, 2, 3, 1, 3, 3, 2, 1,
0, 3, 0, 0, 1, 0, 0, 2, 0, 0, 3, 1, 0, 3, 3, 3, 3, 1, 2, 1, 3, 0,
2, 3, 3, 1, 0, 3, 3, 1, 2, 2, 0, 3, 0, 0, 0, 3, 3, 0, 3, 3, 3, 1,
3, 0, 0, 0, 0, 3, 0, 3, 1, 0, 2, 3, 1, 0, 0, 0, 3, 3, 0, 2, 3, 0,
0, 3, 3, 0, 0, 1, 3, 0, 1, 3, 2, 2, 0, 1, 0, 1, 2, 1, 0, 0, 0, 3,
0, 1, 0, 0, 1, 3, 3, 3, 2, 2, 2, 0, 1, 0, 2, 2, 3, 1, 2, 0, 1, 0,
1, 0, 0, 0, 3, 3, 3, 0, 3, 2, 1, 0, 0, 1, 3, 3, 1, 3, 3, 2, 0, 2,
0, 0, 1, 1, 3, 0, 0, 1, 3, 1, 3, 1, 1, 0, 0, 0, 0, 2, 3, 1, 0, 3,
0, 1, 3, 3, 3, 1, 1, 3, 1, 0, 0, 0, 2, 3, 3, 1, 1, 0, 1, 2, 1, 0,
0, 3, 1, 0, 0, 3, 1, 2, 3, 0, 3, 1, 2, 0, 0, 0, 1, 2, 1, 3, 0, 2,
0, 0, 0, 3, 1, 1, 1, 3, 1, 3, 1, 3, 2, 0, 0, 0, 1, 0, 3, 0, 2, 0,
3, 0, 0, 0, 0, 0, 3, 2, 0, 1, 0, 0, 1, 3, 2, 2, 1, 3, 3, 0, 0, 3,
0, 0, 0, 3, 1, 2, 3, 3, 1, 3, 1, 1, 0, 0, 3, 1, 0, 1, 2, 3, 3, 0,
1, 2, 0, 0, 3, 1, 3, 0, 0, 1, 1, 2, 3, 0, 1, 3, 3, 0, 0, 1, 3, 2,
1, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 3, 1, 3, 0, 0, 0, 0, 1, 0, 3, 3,
0, 0, 1, 1, 1, 2, 1, 0, 0, 1, 3, 1, 1, 3, 0, 3, 3, 0, 3, 1, 0, 0,
0, 3, 3, 2, 3, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 3, 3, 0, 3, 1, 3, 0,
0, 0, 3, 1, 3, 0, 0, 1, 0, 0, 0, 3, 0, 2, 3, 3, 1, 0, 0, 3, 3, 1,
1, 3, 1, 3, 0, 3, 1, 1, 3, 2, 0, 0, 3, 2, 3, 2, 1, 1, 3, 3, 0, 0,
3, 1, 0, 0, 3, 3, 0, 3, 3, 0, 3, 0, 1, 1, 0, 0, 3, 3, 3, 0, 0, 0,
1, 1, 3, 2, 1, 1, 3, 0, 3, 3, 2, 0, 3, 0, 3, 0, 1, 0, 0, 3, 3, 3,
1, 3, 0, 2, 2, 1, 3, 1, 0, 0, 1, 3, 1, 1, 3, 3, 2, 3, 3, 0, 1, 1,
0, 3, 0, 3, 0, 1, 1, 3, 3, 2, 1, 2, 1, 1, 2, 0, 3, 1, 3, 2, 0, 3,
1, 3, 0, 1, 0, 1, 2, 0, 0, 0, 0, 3, 2, 0, 3, 3, 1, 3, 0, 3, 2, 0,
2, 3, 0, 3, 0, 2, 3, 1, 0, 3, 1, 1, 0, 0, 0, 0, 1, 3, 0, 1, 0, 3,
1, 1, 1, 3, 3, 3, 3, 3, 0, 3, 1, 3, 3, 0, 0, 0, 3, 3, 3, 0, 3, 3,
3, 0, 0, 3, 3, 2, 1, 1, 2, 0, 3, 0, 1, 3, 3, 0, 0, 3, 1, 3, 0, 3,
2, 3, 0, 3, 0, 0, 2, 3, 3, 0, 1, 1, 0, 3, 0, 3, 1, 0, 0, 0, 1, 2,
0, 2, 0, 2, 0, 2, 1, 3, 2, 1, 1, 0, 2, 0, 0, 1, 1, 3, 1, 3, 2, 1,
3, 1, 3, 1, 3, 0, 0, 3, 1, 3, 0, 3, 1, 3, 1, 0, 0, 3, 0, 3, 2, 1,
3, 1, 0, 3, 3, 3, 0, 0, 1, 3, 0, 3, 0, 0, 0, 1, 0, 3, 2, 0, 0, 1,
3, 1, 2, 0, 0, 2, 1, 3, 0, 1, 0, 3, 3, 1, 2, 1, 0, 0, 1, 1, 2, 0,
1, 1, 3, 3, 0, 1, 0, 1, 1, 0], dtype=int64)
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# Supposons que votre DataFrame s'appelle 'df'
# Supposons également que vous avez une colonne 'variable_numerique' à découper en classes
# Définir le nombre de bins (intervalles)
num_bins = 4
# Appliquer la découpe en classes avec le nombre de bins défini
df['solde_fin_mois1'] = pd.cut(df['solde_fin_mois'], bins=num_bins)
# Calculer le tableau de contingence entre les classes découpées et la variable cible 'target'
contingency_table = pd.crosstab(df['solde_fin_mois1'], df['target'])
# Effectuer le test du chi2 pour évaluer la corrélation entre les classes et la variable cible
chi2, p, dof, expected = chi2_contingency(contingency_table)
# Afficher les résultats
print("Tableau de contingence :\n", contingency_table)
print("\nRésultats du test du chi2 :")
print("Chi2:", chi2)
print("P-value:", p)
print("Degrés de liberté:", dof)
print("Expected frequencies:\n", expected)
Tableau de contingence : target 0 1 solde_fin_mois1 (1004.665, 13257.424] 180 30 (13257.424, 25461.368] 181 50 (25461.368, 37665.312] 182 49 (37665.312, 49869.255] 181 43 Résultats du test du chi2 : Chi2: 4.762765779340365 P-value: 0.19001593656330115 Degrés de liberté: 3 Expected frequencies: [[169.6875 40.3125 ] [186.65625 44.34375] [186.65625 44.34375] [181. 43. ]]
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# Supposons que votre DataFrame s'appelle 'df'
# Supposons également que vous avez une colonne 'variable_numerique' à découper en classes
# Définir les bornes des intervalles
intervals = [0, 1000, 2000, 3000, np.inf]
labels = ['<1000', '1000-2000', '2000-3000', '>3000']
# Appliquer la découpe en classes
df['solde_fin_mois1'] = pd.cut(df['solde_fin_mois'], bins=intervals, labels=labels)
df.head()
| id | date_arrete | annee | mois | age | anciennete_bancaire_mois | situation_matrimoniale | solde_fin_mois | nb_pret | cumul_crediteur | ... | solde_fin_mois1 | solde_fin_mois_class | cumul_crediteur_class | cumul_debiteur_class | salaire_class | mtn_paiement_par_carte_class | mnt_virement_class | mtn_versement_class | mtn_paye_class | mtn_impaye_class | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 779 | 780 | 2084-12-31 | 2084 | 12 | 44 | 28 | Divorcé | 14884.776931 | 4 | 97256.823565 | ... | >3000 | Q2 | (79966.892, 99935.03] | (80035.222, 99946.068] | (8192.548, 9990.142] | (3984.461, 4980.064] | (12013.206, 16003.335] | (4002.016, 5997.005] | (2008.359, 4003.381] | (3.214, 2010.169] |
| 186 | 187 | 2035-07-31 | 2035 | 7 | 68 | 64 | Célibataire | 15543.609729 | 4 | 39363.552028 | ... | >3000 | Q2 | (20062.479, 40030.617] | (60124.376, 80035.222] | (993.181, 2799.764] | (2988.859, 3984.461] | (16003.335, 19993.464] | (4002.016, 5997.005] | (3.361, 2008.359] | (3.214, 2010.169] |
| 255 | 256 | 2041-04-30 | 2041 | 4 | 45 | 181 | Célibataire | 28623.513122 | 3 | 1200.302727 | ... | >3000 | Q3 | (-5.499, 20062.479] | (20302.684, 40213.53] | (993.181, 2799.764] | (1993.256, 2988.859] | (22.868, 4032.948] | (4002.016, 5997.005] | (5998.404, 7993.426] | (3.214, 2010.169] |
| 856 | 857 | 2091-05-31 | 2091 | 5 | 32 | 175 | Marié | 19426.338557 | 0 | 85085.275732 | ... | >3000 | Q2 | (79966.892, 99935.03] | (20302.684, 40213.53] | (6394.953, 8192.548] | (3984.461, 4980.064] | (4032.948, 8023.077] | (7991.995, 9986.985] | (7993.426, 9988.448] | (3.214, 2010.169] |
| 348 | 349 | 2049-01-31 | 2049 | 1 | 20 | 35 | Célibataire | 2350.781978 | 3 | 32617.025413 | ... | 2000-3000 | Q1 | (20062.479, 40030.617] | (20302.684, 40213.53] | (6394.953, 8192.548] | (1993.256, 2988.859] | (16003.335, 19993.464] | (5997.005, 7991.995] | (3.361, 2008.359] | (3.214, 2010.169] |
5 rows × 48 columns
# Calculer le taux de risque par classe
risk_rate_by_class = df.groupby('solde_fin_mois1')['target'].mean()
print(risk_rate_by_class)
# Calculer l'IV pour chaque classe
def calculate_iv(data, target_column):
grouped = data.groupby(target_column)
groups = data[target_column].unique()
iv_values = []
for group in groups:
obs_group = grouped.get_group(group)
obs_event = obs_group[obs_group['target'] == 1].shape[0]
obs_non_event = obs_group[obs_group['target'] == 0].shape[0]
total_event = data[data['target'] == 1].shape[0]
total_non_event = data[data['target'] == 0].shape[0]
iv = ((obs_event / total_event) - (obs_non_event / total_non_event)) * np.log((obs_event * total_non_event) / (obs_non_event * total_event))
iv_values.append(iv)
return sum(iv_values)
# Supprimer les lignes avec des valeurs manquantes dans les colonnes pertinentes
df = df.dropna(subset=['solde_fin_mois1', 'target'])
iv_value = calculate_iv(df, 'solde_fin_mois1')
print("Information Value (IV) :", iv_value)
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Input In [402], in <cell line: 45>() 42 return sum(iv_values) 43 # Supprimer les lignes avec des valeurs manquantes dans les colonnes pertinentes 44 #df = df.dropna(subset=['solde_fin_mois1', 'target']) ---> 45 iv_value = calculate_iv(df, 'solde_fin_mois1') 46 print("Information Value (IV) :", iv_value) Input In [402], in calculate_iv(data, target_column) 27 def calculate_iv(data, target_column): ---> 28 grouped = data.groupby(target_column) 29 groups = data[target_column].unique() 30 iv_values = [] File ~\anaconda3\lib\site-packages\pandas\core\frame.py:7712, in DataFrame.groupby(self, by, axis, level, as_index, sort, group_keys, squeeze, observed, dropna) 7707 axis = self._get_axis_number(axis) 7709 # https://github.com/python/mypy/issues/7642 7710 # error: Argument "squeeze" to "DataFrameGroupBy" has incompatible type 7711 # "Union[bool, NoDefault]"; expected "bool" -> 7712 return DataFrameGroupBy( 7713 obj=self, 7714 keys=by, 7715 axis=axis, 7716 level=level, 7717 as_index=as_index, 7718 sort=sort, 7719 group_keys=group_keys, 7720 squeeze=squeeze, # type: ignore[arg-type] 7721 observed=observed, 7722 dropna=dropna, 7723 ) File ~\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py:882, in GroupBy.__init__(self, obj, keys, axis, level, grouper, exclusions, selection, as_index, sort, group_keys, squeeze, observed, mutated, dropna) 879 if grouper is None: 880 from pandas.core.groupby.grouper import get_grouper --> 882 grouper, exclusions, obj = get_grouper( 883 obj, 884 keys, 885 axis=axis, 886 level=level, 887 sort=sort, 888 observed=observed, 889 mutated=self.mutated, 890 dropna=self.dropna, 891 ) 893 self.obj = obj 894 self.axis = obj._get_axis_number(axis) File ~\anaconda3\lib\site-packages\pandas\core\groupby\grouper.py:882, in get_grouper(obj, key, axis, level, sort, observed, mutated, validate, dropna) 880 in_axis, level, gpr = False, gpr, None 881 else: --> 882 raise KeyError(gpr) 883 elif isinstance(gpr, Grouper) and gpr.key is not None: 884 # Add key to exclusions 885 exclusions.add(gpr.key) KeyError: 'solde_fin_mois1'
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Supposons que votre DataFrame s'appelle 'df'
# Supposons également que vous avez déjà découpé la variable numérique en classes et calculé le taux de risque et l'IV
# Créer le graphique du taux de risque en fonction des classes découpées
plt.figure(figsize=(10, 6))
plt.bar(risk_rate_by_class.index, risk_rate_by_class.values)
plt.title("Taux de Risque en Fonction des Classes Découpées")
plt.xlabel("Classes Découpées")
plt.ylabel("Taux de Risque")
plt.xticks(rotation=45)
plt.tight_layout()
# Afficher le graphique du taux de risque
plt.show()
# Afficher le graphique d'Information Value (IV)
plt.figure(figsize=(8, 5))
plt.bar("IV", iv_value)
plt.title("Information Value (IV)")
plt.ylabel("IV Value")
plt.tight_layout()
# Afficher le graphique d'IV
plt.show()
df.columns
Index(['id', 'date_arrete', 'annee', 'mois', 'age', 'anciennete_bancaire_mois',
'situation_matrimoniale', 'solde_fin_mois', 'nb_pret',
'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement',
'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye',
'mtn_impaye', 'target', 'anciennete_bancaire_range', 'dettes_cumulees',
'paiement_anormaux', 'salaire_range', 'age_group', 'constante',
'situation_matrimoniale_regroupée', 'marital_status_group',
'situation_Célibataire', 'situation_Divorcé', 'situation_Marié',
'situation_Veuf', 'situation_Célibataire', 'situation_Divorcé',
'situation_Marié', 'situation_Veuf', 'age_bin', 'solde_fin_mois1'],
dtype='object')
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2_contingency
# Supposons que votre DataFrame s'appelle 'df'
# Variables numériques à découper
numeric_vars = ['solde_fin_mois', 'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'mnt_virement', 'mtn_versement',
'mtn_paye', 'mtn_impaye']
# Découper les variables numériques en classes (par exemple, 5 classes)
num_classes = 5
for var in numeric_vars:
df[f'{var}_class'] = pd.cut(df[var], num_classes)
# Calculer le taux de risque (défaut par classe)
def calculate_default_rate(group):
total_clients = group.shape[0]
total_defaults = group['target'].sum()
default_rate = total_defaults / total_clients
return default_rate
default_rates = df.groupby(['annee', 'target'])[numeric_vars].apply(calculate_default_rate).reset_index()
# Calculer l'Information Value (IV)
def calculate_iv(group):
group_size = group.shape[0]
non_default = group['target'].value_counts().get(0, 0)
default = group['target'].value_counts().get(1, 0)
non_default_percent = non_default / group_size
default_percent = default / group_size
if non_default_percent == 0 or default_percent == 0:
return 0
iv = (non_default_percent - default_percent) * np.log(non_default_percent / default_percent)
return iv
iv_values = df.groupby(['annee', 'target'])[numeric_vars].apply(calculate_iv).reset_index()
# Créer des graphiques pour le taux de risque et l'IV
plt.figure(figsize=(12, 6))
# Graphique du taux de risque
plt.subplot(1, 2, 1)
for year in df['annee'].unique():
year_data = default_rates[default_rates['annee'] == year]
plt.plot(year_data['target'], year_data['default_rate'], label=year)
plt.xlabel('Target')
plt.ylabel('Taux de Risque')
plt.title('Taux de Risque en Fonction du Target par Année')
plt.legend()
# Graphique de l'IV
plt.subplot(1, 2, 2)
for year in df['annee'].unique():
year_data = iv_values[iv_values['annee'] == year]
plt.plot(year_data['target'], year_data[0], label=year)
plt.xlabel('Target')
plt.ylabel('Information Value')
plt.title('Information Value en Fonction du Target par Année')
plt.legend()
plt.tight_layout()
plt.show()
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) File ~\anaconda3\lib\site-packages\pandas\core\indexes\base.py:3621, in Index.get_loc(self, key, method, tolerance) 3620 try: -> 3621 return self._engine.get_loc(casted_key) 3622 except KeyError as err: File ~\anaconda3\lib\site-packages\pandas\_libs\index.pyx:136, in pandas._libs.index.IndexEngine.get_loc() File ~\anaconda3\lib\site-packages\pandas\_libs\index.pyx:163, in pandas._libs.index.IndexEngine.get_loc() File pandas\_libs\hashtable_class_helper.pxi:5198, in pandas._libs.hashtable.PyObjectHashTable.get_item() File pandas\_libs\hashtable_class_helper.pxi:5206, in pandas._libs.hashtable.PyObjectHashTable.get_item() KeyError: 'target' The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) Input In [399], in <cell line: 25>() 22 default_rate = total_defaults / total_clients 23 return default_rate ---> 25 default_rates = df.groupby(['annee', 'target'])[numeric_vars].apply(calculate_default_rate).reset_index() 29 # Calculer l'Information Value (IV) 30 def calculate_iv(group): File ~\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py:1414, in GroupBy.apply(self, func, *args, **kwargs) 1412 with option_context("mode.chained_assignment", None): 1413 try: -> 1414 result = self._python_apply_general(f, self._selected_obj) 1415 except TypeError: 1416 # gh-20949 1417 # try again, with .apply acting as a filtering (...) 1421 # fails on *some* columns, e.g. a numeric operation 1422 # on a string grouper column 1424 with self._group_selection_context(): File ~\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py:1455, in GroupBy._python_apply_general(self, f, data, not_indexed_same) 1429 @final 1430 def _python_apply_general( 1431 self, (...) 1434 not_indexed_same: bool | None = None, 1435 ) -> DataFrame | Series: 1436 """ 1437 Apply function f in python space 1438 (...) 1453 data after applying f 1454 """ -> 1455 values, mutated = self.grouper.apply(f, data, self.axis) 1457 if not_indexed_same is None: 1458 not_indexed_same = mutated or self.mutated File ~\anaconda3\lib\site-packages\pandas\core\groupby\ops.py:761, in BaseGrouper.apply(self, f, data, axis) 759 # group might be modified 760 group_axes = group.axes --> 761 res = f(group) 762 if not mutated and not _is_indexed_like(res, group_axes, axis): 763 mutated = True Input In [399], in calculate_default_rate(group) 19 def calculate_default_rate(group): 20 total_clients = group.shape[0] ---> 21 total_defaults = group['target'].sum() 22 default_rate = total_defaults / total_clients 23 return default_rate File ~\anaconda3\lib\site-packages\pandas\core\frame.py:3505, in DataFrame.__getitem__(self, key) 3503 if self.columns.nlevels > 1: 3504 return self._getitem_multilevel(key) -> 3505 indexer = self.columns.get_loc(key) 3506 if is_integer(indexer): 3507 indexer = [indexer] File ~\anaconda3\lib\site-packages\pandas\core\indexes\base.py:3623, in Index.get_loc(self, key, method, tolerance) 3621 return self._engine.get_loc(casted_key) 3622 except KeyError as err: -> 3623 raise KeyError(key) from err 3624 except TypeError: 3625 # If we have a listlike key, _check_indexing_error will raise 3626 # InvalidIndexError. Otherwise we fall through and re-raise 3627 # the TypeError. 3628 self._check_indexing_error(key) KeyError: 'target'
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# Supposons que votre DataFrame s'appelle 'df'
# Supposons également que vous avez les colonnes à découper en classes dans la liste 'numeric_columns'
# Définir le nombre de bins (intervalles)
num_bins = 4
# Liste des colonnes à découper en classes
numeric_columns = ['solde_fin_mois', 'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'mnt_virement', 'mtn_versement', 'mtn_paye', 'mtn_impaye']
# Parcourir chaque colonne numérique
for col in numeric_columns:
# Appliquer la découpe en classes avec le nombre de bins défini
df['{}_class'.format(col)] = pd.cut(df[col], bins=num_bins)
# Calculer le tableau de contingence entre les classes découpées et la variable cible 'target'
contingency_table = pd.crosstab(df['{}_class'.format(col)], df['target'])
# Effectuer le test du chi2 pour évaluer la corrélation entre les classes et la variable cible
chi2, p, dof, expected = chi2_contingency(contingency_table)
# Afficher les résultats pour chaque colonne
print("Colonnes :", col)
print("Tableau de contingence :\n", contingency_table)
print("\nRésultats du test du chi2 :")
print("Chi2:", chi2)
print("P-value:", p)
print("Degrés de liberté:", dof)
print("Expected frequencies:\n", expected)
print("---------------------------------------")
Colonnes : solde_fin_mois Tableau de contingence : target 0 1 solde_fin_mois_class (-4943.74, 8800.578] 201 40 (8800.578, 22490.137] 192 54 (22490.137, 36179.696] 203 58 (36179.696, 49869.255] 205 47 Résultats du test du chi2 : Chi2: 3.4280302305840324 P-value: 0.33021701539615217 Degrés de liberté: 3 Expected frequencies: [[193.041 47.959] [197.046 48.954] [209.061 51.939] [201.852 50.148]] --------------------------------------- Colonnes : cumul_crediteur Tableau de contingence : target 0 1 cumul_crediteur_class (-5.499, 25054.514] 199 48 (25054.514, 50014.686] 200 62 (50014.686, 74974.858] 198 46 (74974.858, 99935.03] 204 43 Résultats du test du chi2 : Chi2: 3.49219289279141 P-value: 0.32177608894637927 Degrés de liberté: 3 Expected frequencies: [[197.847 49.153] [209.862 52.138] [195.444 48.556] [197.847 49.153]] --------------------------------------- Colonnes : cumul_debiteur Tableau de contingence : target 0 1 cumul_debiteur_class (43.031, 25093.643] 204 54 (25093.643, 50044.451] 203 49 (50044.451, 74995.26] 194 45 (74995.26, 99946.068] 200 51 Résultats du test du chi2 : Chi2: 0.4043720929885012 P-value: 0.9393378492146907 Degrés de liberté: 3 Expected frequencies: [[206.658 51.342] [201.852 50.148] [191.439 47.561] [201.051 49.949]] --------------------------------------- Colonnes : salaire Tableau de contingence : target 0 1 salaire_class (993.181, 3249.162] 212 54 (3249.162, 5496.156] 208 45 (5496.156, 7743.149] 195 59 (7743.149, 9990.142] 186 41 Résultats du test du chi2 : Chi2: 2.982260473834268 P-value: 0.3943683567214078 Degrés de liberté: 3 Expected frequencies: [[213.066 52.934] [202.653 50.347] [203.454 50.546] [181.827 45.173]] --------------------------------------- Colonnes : mtn_paiement_par_carte Tableau de contingence : target 0 1 mtn_paiement_par_carte_class (-3.764, 1245.927] 206 54 (1245.927, 2490.639] 225 53 (2490.639, 3735.352] 182 52 (3735.352, 4980.064] 188 40 Résultats du test du chi2 : Chi2: 1.8306299120564349 P-value: 0.6082923150818202 Degrés de liberté: 3 Expected frequencies: [[208.26 51.74 ] [222.678 55.322] [187.434 46.566] [182.628 45.372]] --------------------------------------- Colonnes : mnt_virement Tableau de contingence : target 0 1 mnt_virement_class (22.868, 5030.48] 185 41 (5030.48, 10018.141] 203 49 (10018.141, 15005.803] 196 59 (15005.803, 19993.464] 217 50 Résultats du test du chi2 : Chi2: 2.378353361248101 P-value: 0.49767685734311395 Degrés de liberté: 3 Expected frequencies: [[181.026 44.974] [201.852 50.148] [204.255 50.745] [213.867 53.133]] --------------------------------------- Colonnes : mtn_versement Tableau de contingence : target 0 1 mtn_versement_class (2.061, 2505.773] 207 48 (2505.773, 4999.51] 195 56 (4999.51, 7493.248] 200 43 (7493.248, 9986.985] 199 52 Résultats du test du chi2 : Chi2: 1.9465610606451746 P-value: 0.5835719015912177 Degrés de liberté: 3 Expected frequencies: [[204.255 50.745] [201.051 49.949] [194.643 48.357] [201.051 49.949]] --------------------------------------- Colonnes : mtn_paye Tableau de contingence : target 0 1 mtn_paye_class (3.361, 2507.114] 218 55 (2507.114, 5000.892] 195 51 (5000.892, 7494.67] 185 42 (7494.67, 9988.448] 203 51 Résultats du test du chi2 : Chi2: 0.4005006476861016 P-value: 0.9401390533273641 Degrés de liberté: 3 Expected frequencies: [[218.673 54.327] [197.046 48.954] [181.827 45.173] [203.454 50.546]] --------------------------------------- Colonnes : mtn_impaye Tableau de contingence : target 0 1 mtn_impaye_class (3.214, 2509.412] 186 57 (2509.412, 5005.625] 201 53 (5005.625, 7501.838] 185 48 (7501.838, 9998.051] 229 41 Résultats du test du chi2 : Chi2: 5.914487741917542 P-value: 0.11584551459676018 Degrés de liberté: 3 Expected frequencies: [[194.643 48.357] [203.454 50.546] [186.633 46.367] [216.27 53.73 ]] ---------------------------------------
data = {
'id': range(1, n_samples + 1),
'date_arrete': pd.date_range(start='2020-01-01', periods=n_samples, freq='M'),
'annee': np.random.randint(2020, 2023, size=n_samples),
'mois': np.random.randint(1, 13, size=n_samples),
'age': np.random.randint(20, 70, size=n_samples),
'anciennete_bancaire_mois': np.random.randint(6, 240, size=n_samples),
'situation_matrimoniale': np.random.choice(['Célibataire', 'Marié', 'Divorcé', 'Veuf'], size=n_samples),
'solde_fin_mois': np.random.uniform(-5000, 50000, size=n_samples),
'nb_pret': np.random.randint(0, 5, size=n_samples),
'cumul_crediteur': np.random.uniform(0, 100000, size=n_samples),
'cumul_debiteur': np.random.uniform(0, 100000, size=n_samples),
'salaire': np.random.uniform(1000, 10000, size=n_samples),
'mtn_paiement_par_carte': np.random.uniform(0, 5000, size=n_samples),
'nb_paiement_par_carte': np.random.randint(0, 50, size=n_samples),
'nb_virement': np.random.randint(0, 20, size=n_samples),
'mnt_virement': np.random.uniform(0, 20000, size=n_samples),
'nb_versement': np.random.randint(0, 10, size=n_samples),
'mtn_versement': np.random.uniform(0, 10000, size=n_samples),
'mtn_paye': np.random.uniform(0, 10000, size=n_samples),
'mtn_impaye': np.random.uniform(0, 10000, size=n_samples),
'target': np.random.choice([0, 1], size=n_samples, p=[0.8, 0.2])
}
df = pd.DataFrame(data)
# Supposons que votre DataFrame s'appelle 'df'
# Définir le nombre de bins pour la découpe en classes
num_bins = 3 # Vous pouvez ajuster ce nombre en fonction de vos préférences
# Appliquer la découpe en classes avec le nombre de bins
df['solde_fin_mois_class'] = pd.cut(df['solde_fin_mois'], bins=num_bins, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby(['solde_fin_mois_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = grouped_data[1] / (grouped_data[0] + grouped_data[1])
# Trier le DataFrame par ordre croissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes
plt.figure(figsize=(12, 6))
plt.bar(grouped_data['solde_fin_mois_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title('Taux de Risque en Fonction des Classes (Tri croissant)')
# Afficher les intervalles et les taux de risque correspondants
for i, label in enumerate(labels):
print(label)
interval = labels[i]
risk_rate = grouped_data[grouped_data['solde_fin_mois_class'] == i]['risk_rate'].values[0]
plt.text(i, risk_rate + 0.01, f'Intervalle: {interval}\nTaux de Risque: {risk_rate:.2f}', ha='center')
plt.xticks(range(num_bins), labels) # Changer 'labels' en fonction de la découpe en classes
plt.show()
Faible Moyen Élevé Très élevé
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) Input In [407], in <cell line: 54>() 55 print(label) 56 interval = labels[i] ---> 57 risk_rate = grouped_data[grouped_data['solde_fin_mois_class'] == i]['risk_rate'].values[0] 58 plt.text(i, risk_rate + 0.01, f'Intervalle: {interval}\nTaux de Risque: {risk_rate:.2f}', ha='center') 59 plt.xticks(range(num_bins), labels) # Changer 'labels' en fonction de la découpe en classes IndexError: index 0 is out of bounds for axis 0 with size 0
# Fonction pour découper une variable numérique en classes, calculer le taux de risque et générer le graphique
def analyze_variable(df, variable, num_bins=3):
# Créer des bins
df[f'{variable}_class'] = pd.cut(df[variable], bins=num_bins, labels=False)
# Calculer le taux de risque
grouped_data = df.groupby([f'{variable}_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = grouped_data[1] / (grouped_data[0] + grouped_data[1])
# Trier par taux de risque croissant
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Afficher le graphique
plt.figure(figsize=(12, 6))
plt.bar(grouped_data[f'{variable}_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title(f'Taux de Risque en Fonction des Classes pour {variable}')
# Afficher les intervalles et les taux de risque correspondants
for i, risk_rate in enumerate(grouped_data['risk_rate']):
interval = grouped_data[f'{variable}_class'].iloc[i]
plt.text(i, risk_rate + 0.01, f'Intervalle: {interval}\nTaux de Risque: {risk_rate:.2f}', ha='center')
plt.xticks(range(num_bins))
plt.show()
# Appliquer la fonction pour la variable 'solde_fin_mois'
analyze_variable(df, 'solde_fin_mois', num_bins=3)
df.columns
Index(['id', 'date_arrete', 'annee', 'mois', 'age', 'anciennete_bancaire_mois',
'situation_matrimoniale', 'solde_fin_mois', 'nb_pret',
'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement',
'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye',
'mtn_impaye', 'target'],
dtype='object')
# Créer le DataFrame
np.random.seed(42)
n_samples = 1000
data = {
'id': range(1, n_samples + 1),
'date_arrete': pd.date_range(start='2020-01-01', periods=n_samples, freq='M'),
'annee': np.random.randint(2020, 2023, size=n_samples),
'mois': np.random.randint(1, 13, size=n_samples),
'age': np.random.randint(20, 70, size=n_samples),
'anciennete_bancaire_mois': np.random.randint(6, 240, size=n_samples),
'situation_matrimoniale': np.random.choice(['Célibataire', 'Marié', 'Divorcé', 'Veuf'], size=n_samples),
'solde_fin_mois': np.random.uniform(-5000, 50000, size=n_samples),
'nb_pret': np.random.randint(0, 5, size=n_samples),
'cumul_crediteur': np.random.uniform(0, 100000, size=n_samples),
'cumul_debiteur': np.random.uniform(0, 100000, size=n_samples),
'salaire': np.random.uniform(1000, 10000, size=n_samples),
'mtn_paiement_par_carte': np.random.uniform(0, 5000, size=n_samples),
'nb_paiement_par_carte': np.random.randint(0, 50, size=n_samples),
'nb_virement': np.random.randint(0, 20, size=n_samples),
'mnt_virement': np.random.uniform(0, 20000, size=n_samples),
'nb_versement': np.random.randint(0, 10, size=n_samples),
'mtn_versement': np.random.uniform(0, 10000, size=n_samples),
'mtn_paye': np.random.uniform(0, 10000, size=n_samples),
'mtn_impaye': np.random.uniform(0, 10000, size=n_samples),
'target': np.random.choice([0, 1], size=n_samples, p=[0.8, 0.2])
}
df = pd.DataFrame(data)
# Définir le nombre de classes souhaitées
num_bins = 2# Vous pouvez ajuster ce nombre en fonction de vos préférences
# Calculer les intervalles de classes en utilisant les valeurs continues
solde_fin_mois_min = df['solde_fin_mois'].min()
solde_fin_mois_max = df['solde_fin_mois'].max()
class_intervals = np.linspace(solde_fin_mois_min, solde_fin_mois_max, num_bins + 1)
# Appliquer la découpe en classes en fonction des intervalles calculés
df['solde_fin_mois_class'] = pd.cut(df['solde_fin_mois'], bins=class_intervals, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby(['solde_fin_mois_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = grouped_data[1] / (grouped_data[0] + grouped_data[1])
# Trier le DataFrame par ordre croissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes
plt.figure(figsize=(12, 6))
plt.bar(grouped_data['solde_fin_mois_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title('Taux de Risque en Fonction des Classes (Tri croissant)')
# Afficher les intervalles et les taux de risque correspondants
class_intervals_str = [f'{int(class_intervals[i])}-{int(class_intervals[i+1])}' for i in range(len(class_intervals) - 1)]
for i, interval in enumerate(class_intervals_str):
risk_rate = grouped_data[grouped_data['solde_fin_mois_class'] == i]['risk_rate'].values[0]
plt.text(i, risk_rate + 0.01, f'Taux de Risque: {risk_rate:.2f}', ha='center')
#plt.text(i, risk_rate + 0.01, f'Intervalle: {interval}\nTaux de Risque: {risk_rate:.2f}', ha='center')
plt.xticks(range(num_bins), class_intervals_str) # Utiliser les intervalles comme étiquettes
plt.show()
grouped_data
| target | solde_fin_mois_class | 0 | 1 | risk_rate |
|---|---|---|---|---|
| 0 | 0.0 | 392 | 94 | 0.193416 |
| 1 | 1.0 | 408 | 105 | 0.204678 |
# Créer le DataFrame
np.random.seed(42)
n_samples = 1000
data = {
'id': range(1, n_samples + 1),
'date_arrete': pd.date_range(start='2020-01-01', periods=n_samples, freq='M'),
'annee': np.random.randint(2020, 2023, size=n_samples),
'mois': np.random.randint(1, 13, size=n_samples),
'age': np.random.randint(20, 70, size=n_samples),
'anciennete_bancaire_mois': np.random.randint(6, 240, size=n_samples),
'situation_matrimoniale': np.random.choice(['Célibataire', 'Marié', 'Divorcé', 'Veuf'], size=n_samples),
'solde_fin_mois': np.random.uniform(-5000, 50000, size=n_samples),
'nb_pret': np.random.randint(0, 5, size=n_samples),
'cumul_crediteur': np.random.uniform(0, 100000, size=n_samples),
'cumul_debiteur': np.random.uniform(0, 100000, size=n_samples),
'salaire': np.random.uniform(1000, 10000, size=n_samples),
'mtn_paiement_par_carte': np.random.uniform(0, 5000, size=n_samples),
'nb_paiement_par_carte': np.random.randint(0, 50, size=n_samples),
'nb_virement': np.random.randint(0, 20, size=n_samples),
'mnt_virement': np.random.uniform(0, 20000, size=n_samples),
'nb_versement': np.random.randint(0, 10, size=n_samples),
'mtn_versement': np.random.uniform(0, 10000, size=n_samples),
'mtn_paye': np.random.uniform(0, 10000, size=n_samples),
'mtn_impaye': np.random.uniform(0, 10000, size=n_samples),
'target': np.random.choice([0, 1], size=n_samples, p=[0.8, 0.2])
}
df = pd.DataFrame(data)
# Définir le nombre de classes souhaitées
num_bins = 3# Vous pouvez ajuster ce nombre en fonction de vos préférences
# Calculer les intervalles de classes en utilisant les valeurs continues
solde_fin_mois_min = df['solde_fin_mois'].min()
solde_fin_mois_max = df['solde_fin_mois'].max()
class_intervals = np.linspace(solde_fin_mois_min, solde_fin_mois_max, num_bins + 1)
# Appliquer la découpe en classes en fonction des intervalles calculés
df['solde_fin_mois_class'] = pd.cut(df['solde_fin_mois'], bins=class_intervals, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby(['solde_fin_mois_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = grouped_data[1] / (grouped_data[0] + grouped_data[1])
# Trier le DataFrame par ordre décroissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes triées par taux de risque
plt.figure(figsize=(12, 6))
plt.bar(grouped_data['solde_fin_mois_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title('Taux de Risque en Fonction des Classes (Tri décroissant par taux de risque)')
# Relier les taux de risque avec des lignes
for i in range(1, len(grouped_data)):
plt.plot([i - 1, i], [grouped_data['risk_rate'].iloc[i - 1], grouped_data['risk_rate'].iloc[i]], marker='o', color='black')
# Afficher les intervalles et les taux de risque correspondants
class_intervals_str = [f'{int(class_intervals[i])}-{int(class_intervals[i+1])}' for i in range(len(class_intervals) - 1)]
for i, interval in enumerate(class_intervals_str):
risk_rate = grouped_data['risk_rate'].iloc[i]
plt.text(i, risk_rate + 0.01, f'Taux de Risque: {risk_rate:.2f}', ha='center')
plt.xticks(range(num_bins), class_intervals_str) # Utiliser les intervalles comme étiquettes
plt.show()
grouped_data
| target | solde_fin_mois_class | 0 | 1 | risk_rate |
|---|---|---|---|---|
| 0 | 0.0 | 262 | 57 | 0.178683 |
| 2 | 2.0 | 274 | 68 | 0.198830 |
| 1 | 1.0 | 264 | 74 | 0.218935 |
# Définir les variables numériques que vous souhaitez analyser
variables_to_analyze = ['solde_fin_mois', 'age', 'cumul_crediteur'] # Ajoutez d'autres variables au besoin
# Définir le nombre de classes souhaitées pour chaque variable
num_bins = 3 # Vous pouvez ajuster ce nombre en fonction de vos préférences
# Boucle pour analyser chaque variable
for variable in variables_to_analyze:
# Calculer les intervalles de classes en utilisant les valeurs continues
variable_min = df[variable].min()
variable_max = df[variable].max()
class_intervals = np.linspace(variable_min, variable_max, num_bins + 1)
# Appliquer la découpe en classes en fonction des intervalles calculés
df[f'{variable}_class'] = pd.cut(df[variable], bins=class_intervals, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby([f'{variable}_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = grouped_data[1] / (grouped_data[0] + grouped_data[1])
# Trier le DataFrame par ordre décroissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes triées par taux de risque
plt.figure(figsize=(12, 6))
plt.bar(grouped_data[f'{variable}_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title(f'Taux de Risque en Fonction des Classes pour {variable} (Tri décroissant par taux de risque)')
# Relier les taux de risque avec des lignes
for i in range(1, len(grouped_data)):
plt.plot([i - 1, i], [grouped_data['risk_rate'].iloc[i - 1], grouped_data['risk_rate'].iloc[i]], marker='o', color='black')
# Afficher les intervalles et les taux de risque correspondants
class_intervals_str = [f'{int(class_intervals[i])}-{int(class_intervals[i+1])}' for i in range(len(class_intervals) - 1)]
for i, interval in enumerate(class_intervals_str):
risk_rate = grouped_data['risk_rate'].iloc[i]
plt.text(i, risk_rate + 0.01, f'Taux de Risque: {risk_rate:.2f}', ha='center')
plt.xticks(range(num_bins), class_intervals_str) # Utiliser les intervalles comme étiquettes
plt.show()
from scipy.stats import iqr
# Définir les variables numériques que vous souhaitez analyser
variables_to_analyze = ['solde_fin_mois', 'age', 'cumul_crediteur'] # Ajoutez d'autres variables au besoin
# Boucle pour analyser chaque variable
for variable in variables_to_analyze:
# Utiliser la méthode de Freedman-Diaconis pour déterminer le nombre de classes
iqr_value = iqr(df[variable])
num_bins = int(np.ceil((df[variable].max() - df[variable].min()) / (2 * iqr_value / np.power(len(df[variable]), 1/3))))
# Calculer les intervalles de classes en utilisant les valeurs continues
class_intervals = np.linspace(df[variable].min(), df[variable].max(), num_bins + 1)
# Appliquer la découpe en classes en fonction des intervalles calculés
df[f'{variable}_class'] = pd.cut(df[variable], bins=class_intervals, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby([f'{variable}_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = round(grouped_data[1] / (grouped_data[0] + grouped_data[1]),2)
# Trier le DataFrame par ordre décroissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes triées par taux de risque
plt.figure(figsize=(12, 6))
plt.bar(grouped_data[f'{variable}_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title(f'Taux de Risque en Fonction des Classes pour {variable} (Tri décroissant par taux de risque)')
print(grouped_data)
# Relier les taux de risque avec des lignes
for i in range(1, len(grouped_data)):
plt.plot([i - 1, i], [grouped_data['risk_rate'].iloc[i - 1], grouped_data['risk_rate'].iloc[i]], marker='o', color='black')
# Afficher les intervalles et les taux de risque correspondants
class_intervals_str = [f'{int(class_intervals[i])}-{int(class_intervals[i+1])}' for i in range(len(class_intervals) - 1)]
for i, interval in enumerate(class_intervals_str):
risk_rate = grouped_data['risk_rate'].iloc[i]
plt.text(i, risk_rate + 0.01, f'{risk_rate:.2f}', ha='center')
plt.xticks(range(num_bins), class_intervals_str) # Utiliser les intervalles comme étiquettes
plt.show()
target solde_fin_mois_class 0 1 risk_rate 2 2.0 85 11 0.11 1 1.0 60 9 0.13 9 9.0 74 15 0.17 5 5.0 63 15 0.19 7 7.0 69 16 0.19 4 4.0 83 21 0.20 8 8.0 81 22 0.21 6 6.0 80 23 0.22 3 3.0 70 22 0.24 10 10.0 68 21 0.24 0 0.0 67 24 0.26
target age_class 0 1 risk_rate 5 5.0 60 11 0.15 9 9.0 65 12 0.16 4 4.0 96 19 0.17 1 1.0 62 14 0.18 10 10.0 81 18 0.18 7 7.0 70 16 0.19 2 2.0 79 20 0.20 0 0.0 68 18 0.21 6 6.0 76 22 0.22 8 8.0 74 23 0.24 3 3.0 57 20 0.26
target cumul_crediteur_class 0 1 risk_rate 8 8.0 73 11 0.13 5 5.0 70 11 0.14 9 9.0 63 13 0.17 1 1.0 75 17 0.18 2 2.0 72 17 0.19 6 6.0 76 18 0.19 0 0.0 69 18 0.21 10 10.0 87 23 0.21 3 3.0 87 25 0.22 7 7.0 67 21 0.24 4 4.0 61 25 0.29
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import iqr
# Définir les variables numériques que vous souhaitez analyser
variables_to_analyze = ['solde_fin_mois', 'age', 'cumul_crediteur'] # Ajoutez d'autres variables au besoin
# Boucle pour analyser chaque variable
for variable in variables_to_analyze:
# Utiliser la méthode de Freedman-Diaconis pour déterminer le nombre de classes
iqr_value = iqr(df[variable])
num_bins = int(np.ceil((df[variable].max() - df[variable].min()) / (2 * iqr_value / np.power(len(df[variable]), 1/3))))
# Calculer les intervalles de classes en utilisant les valeurs continues
class_intervals = np.linspace(df[variable].min(), df[variable].max(), num_bins + 1)
# Appliquer la découpe en classes en fonction des intervalles calculés
df[f'{variable}_class'] = pd.cut(df[variable], bins=class_intervals, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby([f'{variable}_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = round(grouped_data[1] / (grouped_data[0] + grouped_data[1]), 2)
# Trier le DataFrame par ordre décroissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes triées par taux de risque
plt.figure(figsize=(12, 6))
plt.bar(grouped_data[f'{variable}_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title(f'Taux de Risque en Fonction des Classes pour {variable} (Tri décroissant par taux de risque)')
# Relier les taux de risque avec des lignes
for i in range(1, len(grouped_data)):
plt.plot([i - 1, i], [grouped_data['risk_rate'].iloc[i - 1], grouped_data['risk_rate'].iloc[i]], marker='o', color='black')
# Afficher les taux de risque correspondants
class_intervals_str = [f'{int(class_intervals[i])}-{int(class_intervals[i+1])}' for i in range(len(class_intervals) - 1)]
for i, interval in enumerate(class_intervals_str):
risk_rate = grouped_data['risk_rate'].iloc[i]
plt.text(i, risk_rate + 0.01, f'{risk_rate:.3f}', ha='center')
plt.xticks(range(num_bins), class_intervals_str) # Utiliser les intervalles comme étiquettes
plt.show()
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# Définir les variables numériques que vous souhaitez analyser
variables_to_analyze = ['solde_fin_mois', 'age', 'cumul_crediteur'] # Ajoutez d'autres variables au besoin
# Boucle pour analyser chaque variable
for variable in variables_to_analyze:
# Utiliser la règle de Scott pour déterminer le nombre de classes
std_dev = np.std(df[variable], ddof=1) # Écart-type non biaisé
num_bins = int(np.ceil((df[variable].max() - df[variable].min()) / (1.5 * std_dev)))
# Calculer les intervalles de classes en utilisant les valeurs continues
class_intervals = np.linspace(df[variable].min(), df[variable].max(), num_bins + 1)
# Appliquer la découpe en classes en fonction des intervalles calculés
df[f'{variable}_class'] = pd.cut(df[variable], bins=class_intervals, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby([f'{variable}_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = round(grouped_data[1] / (grouped_data[0] + grouped_data[1]), 2)
# Trier le DataFrame par ordre décroissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes triées par taux de risque
plt.figure(figsize=(12, 6))
plt.bar(grouped_data[f'{variable}_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title(f'Taux de Risque en Fonction des Classes pour {variable} (Tri décroissant par taux de risque)')
# Relier les taux de risque avec des lignes
for i in range(1, len(grouped_data)):
plt.plot([i - 1, i], [grouped_data['risk_rate'].iloc[i - 1], grouped_data['risk_rate'].iloc[i]], marker='o', color='black')
# Afficher les intervalles et les taux de risque correspondants
class_intervals_str = [f'{int(class_intervals[i])}-{int(class_intervals[i+1])}' for i in range(len(class_intervals) - 1)]
for i, interval in enumerate(class_intervals_str):
risk_rate = grouped_data['risk_rate'].iloc[i]
plt.text(i, risk_rate + 0.01, f'{risk_rate:.2f}', ha='center')
plt.xticks(range(num_bins), class_intervals_str) # Utiliser les intervalles comme étiquettes
plt.show()
# Calculer le nombre optimal de classes en utilisant la règle de Sturges
num_bins = int(np.log2(len(df)) + 1)
# Découper la variable solde_fin_mois en classes avec le nombre optimal de classes
df['solde_fin_mois_bins'] = pd.cut(df['solde_fin_mois'], bins=num_bins)
# Calculer le taux de risque par classe
risk_rates = df.groupby('solde_fin_mois_bins')['target'].mean().reset_index()
risk_rates.rename(columns={'target': 'Risk Rate'}, inplace=True)
# Calculer l'IV pour chaque classe
def calculate_iv(data, variable_bin):
obs = pd.crosstab(data[variable_bin], data['target'])
chi2, p, dof, expected = chi2_contingency(obs)
iv = np.sum((obs / np.sum(obs)) * np.log((obs / np.sum(obs)) / (expected / np.sum(expected))))
return iv
iv_values = []
for bin_label in df['solde_fin_mois_bins'].unique():
iv = calculate_iv(df[df['solde_fin_mois_bins'] == bin_label], 'solde_fin_mois_bins')
iv_values.append({'solde_fin_mois_bins': bin_label, 'IV': iv})
iv_df = pd.DataFrame(iv_values)
# Trier les classes par ordre décroissant d'IV
sorted_iv_df = iv_df.sort_values(by='IV', ascending=False)
sorted_bins = sorted_iv_df['solde_fin_mois_bins']
# Réorganiser les catégories pour suivre l'ordre trié
df['solde_fin_mois_bins'] = df['solde_fin_mois_bins'].cat.set_categories(sorted_bins)
# Trier le DataFrame par ordre décroissant du taux de risque
risk_rates = df.groupby('solde_fin_mois_bins')['Risk Rate'].mean().reset_index()
risk_rates = risk_rates.sort_values(by='Risk Rate', ascending=False)
# Créer un graphique du taux de risque en fonction des classes triées par IV
plt.figure(figsize=(12, 6))
plt.bar(risk_rates['solde_fin_mois_bins'].astype(str), risk_rates['Risk Rate'])
plt.xlabel('Intervalle de Solde Fin Mois')
plt.ylabel('Taux de Risque')
plt.title('Taux de Risque en Fonction des Intervales Continus de Solde Fin Mois (Trié par IV)')
# Afficher les taux de risque pour chaque classe
for i, row in risk_rates.iterrows():
interval = row['solde_fin_mois_bins']
risk_rate = row['Risk Rate']
plt.text(i, risk_rate + 0.01, f'Intervalle: {interval}\nTaux de Risque: {risk_rate:.2f}', ha='center')
plt.xticks(range(len(risk_rates)), risk_rates['solde_fin_mois_bins'].astype(str), rotation=45)
plt.tight_layout()
plt.show()
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [446], in <cell line: 26>() 23 iv_df = pd.DataFrame(iv_values) 25 # Trier les classes par ordre décroissant d'IV ---> 26 sorted_iv_df = iv_df.sort_values(by='IV', ascending=False) 27 sorted_bins = sorted_iv_df['solde_fin_mois_bins'] 29 # Réorganiser les catégories pour suivre l'ordre trié File ~\anaconda3\lib\site-packages\pandas\util\_decorators.py:311, in deprecate_nonkeyword_arguments.<locals>.decorate.<locals>.wrapper(*args, **kwargs) 305 if len(args) > num_allow_args: 306 warnings.warn( 307 msg.format(arguments=arguments), 308 FutureWarning, 309 stacklevel=stacklevel, 310 ) --> 311 return func(*args, **kwargs) File ~\anaconda3\lib\site-packages\pandas\core\frame.py:6324, in DataFrame.sort_values(self, by, axis, ascending, inplace, kind, na_position, ignore_index, key) 6321 if isinstance(ascending, (tuple, list)): 6322 ascending = ascending[0] -> 6324 indexer = nargsort( 6325 k, kind=kind, ascending=ascending, na_position=na_position, key=key 6326 ) 6327 else: 6328 return self.copy() File ~\anaconda3\lib\site-packages\pandas\core\sorting.py:417, in nargsort(items, kind, ascending, na_position, key, mask) 415 non_nans = non_nans[::-1] 416 non_nan_idx = non_nan_idx[::-1] --> 417 indexer = non_nan_idx[non_nans.argsort(kind=kind)] 418 if not ascending: 419 indexer = indexer[::-1] File ~\anaconda3\lib\site-packages\pandas\core\generic.py:1527, in NDFrame.__nonzero__(self) 1525 @final 1526 def __nonzero__(self): -> 1527 raise ValueError( 1528 f"The truth value of a {type(self).__name__} is ambiguous. " 1529 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." 1530 ) ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
df['solde_fin_mois_bins']
0 (586.842, 6062.666]
1 (586.842, 6062.666]
2 (-4943.74, 586.842]
3 (11538.49, 17014.313]
4 (586.842, 6062.666]
...
995 (22490.137, 27965.961]
996 (33441.784, 38917.608]
997 (11538.49, 17014.313]
998 (17014.313, 22490.137]
999 (586.842, 6062.666]
Name: solde_fin_mois_bins, Length: 1000, dtype: category
Categories (10, interval[float64, right]): [(-4943.74, 586.842] < (586.842, 6062.666] < (6062.666, 11538.49] < (11538.49, 17014.313] ... (27965.961, 33441.784] < (33441.784, 38917.608] < (38917.608, 44393.432] < (44393.432, 49869.255]]
# Créer le DataFrame
np.random.seed(42)
n_samples = 1000
data = {
'id': range(1, n_samples + 1),
'date_arrete': pd.date_range(start='2020-01-01', periods=n_samples, freq='M'),
'annee': np.random.randint(2020, 2023, size=n_samples),
'mois': np.random.randint(1, 13, size=n_samples),
'age': np.random.randint(20, 70, size=n_samples),
'anciennete_bancaire_mois': np.random.randint(6, 240, size=n_samples),
'situation_matrimoniale': np.random.choice(['Célibataire', 'Marié', 'Divorcé', 'Veuf'], size=n_samples),
'solde_fin_mois': np.random.uniform(-5000, 50000, size=n_samples),
'nb_pret': np.random.randint(0, 5, size=n_samples),
'cumul_crediteur': np.random.uniform(0, 100000, size=n_samples),
'cumul_debiteur': np.random.uniform(0, 100000, size=n_samples),
'salaire': np.random.uniform(1000, 10000, size=n_samples),
'mtn_paiement_par_carte': np.random.uniform(0, 5000, size=n_samples),
'nb_paiement_par_carte': np.random.randint(0, 50, size=n_samples),
'nb_virement': np.random.randint(0, 20, size=n_samples),
'mnt_virement': np.random.uniform(0, 20000, size=n_samples),
'nb_versement': np.random.randint(0, 10, size=n_samples),
'mtn_versement': np.random.uniform(0, 10000, size=n_samples),
'mtn_paye': np.random.uniform(0, 10000, size=n_samples),
'mtn_impaye': np.random.uniform(0, 10000, size=n_samples),
'target': np.random.choice([0, 1], size=n_samples, p=[0.8, 0.2])
}
df = pd.DataFrame(data)
# Calculer le taux de risque par classe
risk_rate_by_class = df.groupby('solde_fin_mois')['target'].mean()
print(risk_rate_by_class)
# Calculer l'IV pour chaque classe
def calculate_iv(data, target_column):
grouped = data.groupby(target_column)
groups = data[target_column].unique()
iv_values = []
for group in groups:
obs_group = grouped.get_group(group)
obs_event = obs_group[obs_group['target'] == 1].shape[0]
obs_non_event = obs_group[obs_group['target'] == 0].shape[0]
total_event = data[data['target'] == 1].shape[0]
total_non_event = data[data['target'] == 0].shape[0]
iv = ((obs_event / total_event) - (obs_non_event / total_non_event)) * np.log((obs_event * total_non_event) / (obs_non_event * total_event))
iv_values.append(iv)
return sum(iv_values)
# Supprimer les lignes avec des valeurs manquantes dans les colonnes pertinentes
df = df.dropna(subset=['solde_fin_mois', 'target'])
iv_value = calculate_iv(df, 'solde_fin_mois')
print("Information Value (IV) :", iv_value)
solde_fin_mois
-4888.981524 0.0
-4827.250167 0.0
-4723.539606 0.0
-4705.961153 0.0
-4685.478025 1.0
...
49543.284035 1.0
49547.508454 1.0
49794.425759 1.0
49801.906152 0.0
49869.255224 0.0
Name: target, Length: 1000, dtype: float64
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) Input In [5], in <cell line: 53>() 51 # Supprimer les lignes avec des valeurs manquantes dans les colonnes pertinentes 52 df = df.dropna(subset=['solde_fin_mois', 'target']) ---> 53 iv_value = calculate_iv(df, 'solde_fin_mois') 54 print("Information Value (IV) :", iv_value) Input In [5], in calculate_iv(data, target_column) 44 total_event = data[data['target'] == 1].shape[0] 45 total_non_event = data[data['target'] == 0].shape[0] ---> 47 iv = ((obs_event / total_event) - (obs_non_event / total_non_event)) * np.log((obs_event * total_non_event) / (obs_non_event * total_event)) 48 iv_values.append(iv) 50 return sum(iv_values) ZeroDivisionError: division by zero
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Supposons que votre DataFrame s'appelle 'df'
# Définir le nombre de bins pour la découpe en classes
num_bins = 3 # Vous pouvez ajuster ce nombre en fonction de vos préférences
# Appliquer la découpe en classes avec le nombre de bins
df['solde_fin_mois_class'] = pd.cut(df['solde_fin_mois'], bins=num_bins, labels=False)
# Calculer le taux de risque par classe
grouped_data = df.groupby(['solde_fin_mois_class', 'target']).size().unstack().reset_index()
grouped_data.fillna(0, inplace=True)
grouped_data['risk_rate'] = grouped_data[1] / (grouped_data[0] + grouped_data[1])
# Trier le DataFrame par ordre croissant du taux de risque
grouped_data = grouped_data.sort_values(by='risk_rate', ascending=True)
# Créer un graphique du taux de risque en fonction des classes
plt.figure(figsize=(12, 6))
plt.bar(grouped_data['solde_fin_mois_class'], grouped_data['risk_rate'])
plt.xlabel('Classe')
plt.ylabel('Taux de Risque')
plt.title('Taux de Risque en Fonction des Classes (Tri croissant)')
plt.xticks(range(num_bins), labels) # Changer 'labels' en fonction de la découpe en classes
# Afficher les intervalles et les taux de risque correspondants
for i, label in enumerate(labels):
interval = labels[i]
risk_rate = grouped_data[grouped_data['solde_fin_mois_class'] == i]['risk_rate'].values[0]
plt.text(i, risk_rate + 0.01, f'Intervalle: {interval}\nTaux de Risque: {risk_rate:.2f}', ha='center')
plt.show()
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) Input In [400], in <cell line: 31>() 31 for i, label in enumerate(labels): 32 interval = labels[i] ---> 33 risk_rate = grouped_data[grouped_data['solde_fin_mois_class'] == i]['risk_rate'].values[0] 34 plt.text(i, risk_rate + 0.01, f'Intervalle: {interval}\nTaux de Risque: {risk_rate:.2f}', ha='center') 36 plt.show() IndexError: index 0 is out of bounds for axis 0 with size 0
df.columns
Index(['id', 'date_arrete', 'annee', 'mois', 'age', 'anciennete_bancaire_mois',
'situation_matrimoniale', 'solde_fin_mois', 'nb_pret',
'cumul_crediteur', 'cumul_debiteur', 'salaire',
'mtn_paiement_par_carte', 'nb_paiement_par_carte', 'nb_virement',
'mnt_virement', 'nb_versement', 'mtn_versement', 'mtn_paye',
'mtn_impaye', 'target'],
dtype='object')
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# Supposons que votre DataFrame s'appelle 'df'
# Fonction pour découper une variable numérique en classes en fonction de l'IV
def discretize_variable_by_iv(data, variable, target, max_bins=10, min_bin_size=0.05):
iv_values = []
iv_values_dict = {}
df = data.copy()
while True:
binning_success = False
# Utilisez une boucle pour essayer de trouver le nombre optimal de bins
for num_bins in range(2, max_bins + 1):
# Découpez la variable en classes
df[f'{variable}_bin'] = pd.cut(df[variable], bins=num_bins, precision=2, duplicates='drop')
# Calculez l'IV pour cette découpe
iv = calculate_iv(df, f'{variable}_bin', target)
if iv > min_bin_size:
binning_success = True
iv_values.append({'Variable': variable, 'Bins': num_bins, 'IV': iv})
iv_values_dict[num_bins] = iv
if not binning_success:
break
# Trouvez le nombre de bins avec le meilleur IV
best_num_bins = max(iv_values_dict, key=iv_values_dict.get)
# Appliquez la meilleure découpe en classes
df[f'{variable}_bin'] = pd.cut(df[variable], bins=best_num_bins, precision=2, duplicates='drop')
return df
# Fonction pour calculer l'IV
def calculate_iv(data, variable_bin, target):
obs = pd.crosstab(data[variable_bin], data[target])
chi2, p, dof, expected = chi2_contingency(obs)
iv = np.sum((obs / np.sum(obs)) * np.log((obs / np.sum(obs)) / (expected / np.sum(expected))))
return iv
# Appliquer la découpe en classes en fonction de l'IV pour la variable 'anciennete_bancaire_mois'
df = discretize_variable_by_iv(df, 'anciennete_bancaire_mois', 'target')
# Calculer l'IV pour chaque classe de la variable 'anciennete_bancaire_mois'
iv_values = []
for bin_label in df['anciennete_bancaire_mois_bin'].unique():
iv = calculate_iv(df[df['anciennete_bancaire_mois_bin'] == bin_label], 'anciennete_bancaire_mois_bin', 'target')
iv_values.append({'anciennete_bancaire_mois_bin': bin_label, 'IV': iv})
iv_df = pd.DataFrame(iv_values)
# Afficher le tableau IV pour chaque classe de 'anciennete_bancaire_mois'
print(iv_df)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [18], in <cell line: 48>() 45 return iv 47 # Appliquer la découpe en classes en fonction de l'IV pour la variable 'anciennete_bancaire_mois' ---> 48 df = discretize_variable_by_iv(df, 'anciennete_bancaire_mois', 'target') 50 # Calculer l'IV pour chaque classe de la variable 'anciennete_bancaire_mois' 51 iv_values = [] Input In [18], in discretize_variable_by_iv(data, variable, target, max_bins, min_bin_size) 21 # Calculez l'IV pour cette découpe 22 iv = calculate_iv(df, f'{variable}_bin', target) ---> 24 if iv > min_bin_size: 25 binning_success = True 26 iv_values.append({'Variable': variable, 'Bins': num_bins, 'IV': iv}) File ~\anaconda3\lib\site-packages\pandas\core\generic.py:1527, in NDFrame.__nonzero__(self) 1525 @final 1526 def __nonzero__(self): -> 1527 raise ValueError( 1528 f"The truth value of a {type(self).__name__} is ambiguous. " 1529 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." 1530 ) ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# Fonction pour découper une variable numérique en classes en fonction de l'IV
def discretize_variable_by_iv(data, variable, target, max_bins=10, min_bin_size=0.05):
iv_values = []
iv_values_dict = {}
df = data.copy()
while True:
binning_success = False
# Utilisez une boucle pour essayer de trouver le nombre optimal de bins
for num_bins in range(2, max_bins + 1):
# Découpez la variable en classes
df[f'{variable}_bin'] = pd.cut(df[variable], bins=num_bins, precision=2, duplicates='drop')
# Calculez l'IV pour cette découpe
iv = calculate_iv(df, f'{variable}_bin', target)
if iv > min_bin_size:
binning_success = True
iv_values.append({'Variable': variable, 'Bins': num_bins, 'IV': iv})
iv_values_dict[num_bins] = iv
if not binning_success:
break
# Trouvez le nombre de bins avec le meilleur IV
best_num_bins = max(iv_values_dict, key=iv_values_dict.get)
# Appliquez la meilleure découpe en classes
df[f'{variable}_bin'] = pd.cut(df[variable], bins=best_num_bins, precision=2, duplicates='drop')
return df # Retournez le DataFrame modifié
# Fonction pour calculer l'IV
def calculate_iv(data, variable_bin, target):
obs = pd.crosstab(data[variable_bin], data[target])
chi2, p, dof, expected = chi2_contingency(obs)
iv = np.sum((obs / np.sum(obs)) * np.log((obs / np.sum(obs)) / (expected / np.sum(expected))))
return iv
# Appliquer la découpe en classes en fonction de l'IV pour la variable 'anciennete_bancaire_mois'
df = discretize_variable_by_iv(df, 'anciennete_bancaire_mois', 'target')
# Calculer l'IV pour chaque classe de la variable 'anciennete_bancaire_mois'
iv_values = []
for bin_label in df['anciennete_bancaire_mois_bin'].unique():
iv = calculate_iv(df[df['anciennete_bancaire_mois_bin'] == bin_label], 'anciennete_bancaire_mois_bin', 'target')
iv_values.append({'anciennete_bancaire_mois_bin': bin_label, 'IV': iv})
iv_df = pd.DataFrame(iv_values)
# Afficher le tableau IV pour chaque classe de 'anciennete_bancaire_mois'
print(iv_df)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [23], in <cell line: 46>() 43 return iv 45 # Appliquer la découpe en classes en fonction de l'IV pour la variable 'anciennete_bancaire_mois' ---> 46 df = discretize_variable_by_iv(df, 'anciennete_bancaire_mois', 'target') 48 # Calculer l'IV pour chaque classe de la variable 'anciennete_bancaire_mois' 49 iv_values = [] Input In [23], in discretize_variable_by_iv(data, variable, target, max_bins, min_bin_size) 19 # Calculez l'IV pour cette découpe 20 iv = calculate_iv(df, f'{variable}_bin', target) ---> 22 if iv > min_bin_size: 23 binning_success = True 24 iv_values.append({'Variable': variable, 'Bins': num_bins, 'IV': iv}) File ~\anaconda3\lib\site-packages\pandas\core\generic.py:1527, in NDFrame.__nonzero__(self) 1525 @final 1526 def __nonzero__(self): -> 1527 raise ValueError( 1528 f"The truth value of a {type(self).__name__} is ambiguous. " 1529 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." 1530 ) ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
df
| id | date_arrete | annee | mois | age | anciennete_bancaire_mois | situation_matrimoniale | solde_fin_mois | nb_pret | cumul_crediteur | ... | salaire | mtn_paiement_par_carte | nb_paiement_par_carte | nb_virement | mnt_virement | nb_versement | mtn_versement | mtn_paye | mtn_impaye | target | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 2020-01-31 | 2022 | 7 | 56 | 52 | Célibataire | 3954.827732 | 1 | 76944.257942 | ... | 5294.317384 | 1149.591854 | 32 | 15 | 5235.057381 | 9 | 8444.056123 | 9535.722238 | 6268.536213 | 0 |
| 1 | 2 | 2020-02-29 | 2020 | 3 | 51 | 83 | Veuf | 5280.294233 | 4 | 93479.551749 | ... | 2177.930247 | 2579.729393 | 32 | 9 | 10251.818505 | 0 | 4532.997386 | 8396.244959 | 736.182615 | 0 |
| 2 | 3 | 2020-03-31 | 2022 | 3 | 60 | 129 | Veuf | -3911.238791 | 3 | 90920.213621 | ... | 3120.093411 | 1267.468766 | 43 | 16 | 6612.016199 | 0 | 7264.413581 | 4260.008105 | 1896.963649 | 0 |
| 3 | 4 | 2020-04-30 | 2022 | 8 | 22 | 80 | Divorcé | 16487.516104 | 4 | 81962.486955 | ... | 9392.535578 | 4702.686506 | 19 | 0 | 17210.229732 | 6 | 955.362076 | 6447.168378 | 3378.538857 | 0 |
| 4 | 5 | 2020-05-31 | 2020 | 5 | 47 | 108 | Divorcé | 5528.522427 | 2 | 88819.134966 | ... | 8735.526781 | 4529.719840 | 46 | 17 | 9475.203075 | 2 | 3960.243463 | 1770.709219 | 778.700643 | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 995 | 996 | 2102-12-31 | 2021 | 2 | 67 | 121 | Divorcé | 25107.816221 | 3 | 41616.094641 | ... | 1188.185611 | 614.555913 | 13 | 8 | 8269.942741 | 1 | 4441.442022 | 4090.077367 | 4718.429748 | 1 |
| 996 | 997 | 2103-01-31 | 2021 | 6 | 66 | 178 | Divorcé | 35364.795735 | 2 | 16653.851350 | ... | 3007.810166 | 1015.352965 | 35 | 16 | 8471.716538 | 6 | 6344.399412 | 5239.742027 | 8688.507518 | 0 |
| 997 | 998 | 2103-02-28 | 2022 | 2 | 46 | 86 | Marié | 14060.731790 | 4 | 98617.679728 | ... | 1508.641217 | 2009.759623 | 7 | 17 | 14052.542126 | 1 | 8276.794072 | 1348.748464 | 4148.479698 | 0 |
| 998 | 999 | 2103-03-31 | 2022 | 3 | 34 | 86 | Veuf | 17424.367387 | 1 | 82084.900926 | ... | 1930.554430 | 4228.724392 | 39 | 12 | 18855.440022 | 4 | 4276.929091 | 259.822937 | 5346.595667 | 0 |
| 999 | 1000 | 2103-04-30 | 2020 | 6 | 25 | 118 | Veuf | 1906.106825 | 3 | 28147.730245 | ... | 4883.573079 | 1731.330254 | 21 | 0 | 5341.218805 | 6 | 6411.194651 | 1528.058093 | 201.949231 | 1 |
1000 rows × 21 columns
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# Supposons que votre DataFrame s'appelle 'df'
# Et que vous voulez calculer l'IV pour la variable 'age' par exemple
# Calculer le taux de risque pour chaque classe
risk_rates = df.groupby('age')['target'].mean().reset_index()
risk_rates.rename(columns={'target': 'Risk Rate'}, inplace=True)
# Calculer l'information value pour chaque classe
def calculate_iv(data, variable):
obs = pd.crosstab(data[variable], data['target'])
chi2, p, dof, expected = chi2_contingency(obs)
iv = np.sum((obs / np.sum(obs)) * np.log((obs / np.sum(obs)) / (expected / np.sum(expected))))
#print("obs",obs)
#print("p",p)#0,95
#print("dof",dof)#49
#print("expected",expected)
return iv
iv = calculate_iv(df, 'age')
# Afficher le taux de risque et la valeur d'IV
print(risk_rates)
print(f'IV for age: {iv:.2f}')
age Risk Rate 0 20 0.315789 1 21 0.230769 2 22 0.250000 3 23 0.160000 4 24 0.210526 5 25 0.166667 6 26 0.200000 7 27 0.153846 8 28 0.235294 9 29 0.190476 10 30 0.235294 11 31 0.315789 12 32 0.100000 13 33 0.181818 14 34 0.333333 15 35 0.263158 16 36 0.200000 17 37 0.210526 18 38 0.157895 19 39 0.190476 20 40 0.147059 21 41 0.200000 22 42 0.142857 23 43 0.117647 24 44 0.291667 25 45 0.000000 26 46 0.153846 27 47 0.157895 28 48 0.263158 29 49 0.263158 30 50 0.315789 31 51 0.136364 32 52 0.055556 33 53 0.100000 34 54 0.250000 35 55 0.291667 36 56 0.291667 37 57 0.333333 38 58 0.210526 39 59 0.117647 40 60 0.210526 41 61 0.150000 42 62 0.066667 43 63 0.181818 44 64 0.200000 45 65 0.222222 46 66 0.238095 47 67 0.142857 48 68 0.208333 49 69 0.090909
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Input In [16], in <cell line: 27>() 25 # Afficher le taux de risque et la valeur d'IV 26 print(risk_rates) ---> 27 print(f'IV for age: {iv:.2f}') TypeError: unsupported format string passed to Series.__format__
iv
target 0 0.226061 1 1.692091 dtype: float64
savoir si les variables explicatives sont approximativement linéaires ou nonD
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Charger le jeu de données (remplacez 'data.csv' par le nom de votre fichier de données)
df = pd.read_csv('data.csv')
# Remplacez 'Variable_cible' par le nom de votre variable cible
target_variable = 'Variable_cible'
# Liste des variables explicatives (toutes sauf la variable cible)
explanatory_variables = [col for col in df.columns if col != target_variable]
# Parcourir chaque variable explicative
for var in explanatory_variables:
# Créer un nouveau graphique
plt.figure(figsize=(10, 5))
# Graphique de dispersion
plt.subplot(131)
plt.scatter(df[var], df[target_variable], alpha=0.5)
plt.title(f'Scatter Plot: {var} vs. {target_variable}')
plt.xlabel(var)
plt.ylabel(target_variable)
# Coefficient de corrélation de Pearson
plt.subplot(132)
correlation = df[var].corr(df[target_variable])
sns.regplot(x=var, y=target_variable, data=df, scatter_kws={'alpha':0.5})
plt.title(f'Correlation: {correlation:.2f}')
plt.xlabel(var)
plt.ylabel(target_variable)
# Graphique de régression linéaire
plt.subplot(133)
sns.lmplot(x=var, y=target_variable, data=df, scatter_kws={'alpha':0.5})
plt.title(f'Linear Regression: {var} vs. {target_variable}')
# Afficher les graphiques
plt.tight_layout()
plt.show()
--------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) Input In [269], in <cell line: 6>() 3 import seaborn as sns 5 # Charger le jeu de données (remplacez 'data.csv' par le nom de votre fichier de données) ----> 6 df = pd.read_csv('data.csv') 8 # Remplacez 'Variable_cible' par le nom de votre variable cible 9 target_variable = 'Variable_cible' File ~\anaconda3\lib\site-packages\pandas\util\_decorators.py:311, in deprecate_nonkeyword_arguments.<locals>.decorate.<locals>.wrapper(*args, **kwargs) 305 if len(args) > num_allow_args: 306 warnings.warn( 307 msg.format(arguments=arguments), 308 FutureWarning, 309 stacklevel=stacklevel, 310 ) --> 311 return func(*args, **kwargs) File ~\anaconda3\lib\site-packages\pandas\io\parsers\readers.py:680, in read_csv(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, squeeze, prefix, mangle_dupe_cols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, error_bad_lines, warn_bad_lines, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options) 665 kwds_defaults = _refine_defaults_read( 666 dialect, 667 delimiter, (...) 676 defaults={"delimiter": ","}, 677 ) 678 kwds.update(kwds_defaults) --> 680 return _read(filepath_or_buffer, kwds) File ~\anaconda3\lib\site-packages\pandas\io\parsers\readers.py:575, in _read(filepath_or_buffer, kwds) 572 _validate_names(kwds.get("names", None)) 574 # Create the parser. --> 575 parser = TextFileReader(filepath_or_buffer, **kwds) 577 if chunksize or iterator: 578 return parser File ~\anaconda3\lib\site-packages\pandas\io\parsers\readers.py:933, in TextFileReader.__init__(self, f, engine, **kwds) 930 self.options["has_index_names"] = kwds["has_index_names"] 932 self.handles: IOHandles | None = None --> 933 self._engine = self._make_engine(f, self.engine) File ~\anaconda3\lib\site-packages\pandas\io\parsers\readers.py:1217, in TextFileReader._make_engine(self, f, engine) 1213 mode = "rb" 1214 # error: No overload variant of "get_handle" matches argument types 1215 # "Union[str, PathLike[str], ReadCsvBuffer[bytes], ReadCsvBuffer[str]]" 1216 # , "str", "bool", "Any", "Any", "Any", "Any", "Any" -> 1217 self.handles = get_handle( # type: ignore[call-overload] 1218 f, 1219 mode, 1220 encoding=self.options.get("encoding", None), 1221 compression=self.options.get("compression", None), 1222 memory_map=self.options.get("memory_map", False), 1223 is_text=is_text, 1224 errors=self.options.get("encoding_errors", "strict"), 1225 storage_options=self.options.get("storage_options", None), 1226 ) 1227 assert self.handles is not None 1228 f = self.handles.handle File ~\anaconda3\lib\site-packages\pandas\io\common.py:789, in get_handle(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options) 784 elif isinstance(handle, str): 785 # Check whether the filename is to be opened in binary mode. 786 # Binary mode does not support 'encoding' and 'newline'. 787 if ioargs.encoding and "b" not in ioargs.mode: 788 # Encoding --> 789 handle = open( 790 handle, 791 ioargs.mode, 792 encoding=ioargs.encoding, 793 errors=errors, 794 newline="", 795 ) 796 else: 797 # Binary mode 798 handle = open(handle, ioargs.mode) FileNotFoundError: [Errno 2] No such file or directory: 'data.csv'
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
# Créer un DataFrame fictif (vous pouvez remplacer par vos données réelles)
df = pd.DataFrame({
'Age': np.random.randint(20, 70, size=100),
'Salaire': np.random.uniform(1000, 10000, size=100),
'Nb_Prets': np.random.randint(0, 5, size=100),
'Risque_Defaut': np.random.choice([0, 1], size=100)
})
# Point 1: Calcul des corrélations
correlation_matrix = df.corr()
print("Matrice de corrélation :")
print(correlation_matrix)
# Point 2: Visualisation
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
sns.scatterplot(x='Age', y='Risque_Defaut', data=df)
plt.title('Relation entre l\'âge et le risque de défaut')
plt.subplot(1, 2, 2)
sns.scatterplot(x='Salaire', y='Risque_Defaut', data=df)
plt.title('Relation entre le salaire et le risque de défaut')
plt.tight_layout()
plt.show()
# Point 3: Test statistique (exemple avec l'âge)
age_risque_0 = df[df['Risque_Defaut'] == 0]['Age']
age_risque_1 = df[df['Risque_Defaut'] == 1]['Age']
t_stat, p_value = stats.ttest_ind(age_risque_0, age_risque_1)
print("\nTest de Student pour l'âge :")
print(f"Statistique t : {t_stat}")
print(f"Valeur de p : {p_value}")
# Point 4: Utilisation de modèles linéaires (exemple avec l'âge)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
X = df[['Age']] # Variable explicative
y = df['Risque_Defaut'] # Variable cible
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("\nPrécision du modèle de régression logistique (âge) :", accuracy)
# Point 5: Analyse des résidus (non montrée ici, car nécessite un modèle complet)
# Point 6: Validation croisée (non montrée ici, mais fortement recommandée)
Matrice de corrélation :
Age Salaire Nb_Prets Risque_Defaut
Age 1.000000 0.036856 0.080003 0.012623
Salaire 0.036856 1.000000 0.059435 -0.075560
Nb_Prets 0.080003 0.059435 1.000000 0.173759
Risque_Defaut 0.012623 -0.075560 0.173759 1.000000
Test de Student pour l'âge : Statistique t : -0.12496693224153844 Valeur de p : 0.900805717884319 Précision du modèle de régression logistique (âge) : 0.35
import pandas as pd
import numpy as np
from scipy.stats import f_oneway, ttest_ind
# Supposons que votre DataFrame s'appelle 'df'
# Supposons également que vous avez des variables explicatives numériques 'age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'salaire'
# Liste des variables explicatives numériques
numeric_variables = ['age', 'anciennete_bancaire_mois', 'solde_fin_mois', 'salaire']
# Boucle pour effectuer le test ANOVA pour chaque variable explicative
for variable in numeric_variables:
groups = []
for category in df['target'].unique():
group = df[df['target'] == category][variable]
groups.append(group)
# Effectuer le test ANOVA
f_statistic, p_value = f_oneway(*groups)
print(f"Variable : {variable}")
print(f"Statistique de l'ANOVA : {f_statistic}")
print(f"Valeur de p : {p_value}")
# Interprétation du résultat
if p_value < 0.05:
print("La variable a un effet significatif sur la variable cible.")
else:
print("La variable n'a pas un effet significatif sur la variable cible.")
print("\n")
# Boucle pour effectuer le test t de Student pour chaque variable explicative
for variable in numeric_variables:
group1 = df[df['target'] == 0][variable]
group2 = df[df['target'] == 1][variable]
# Effectuer le test t de Student
t_statistic, p_value = ttest_ind(group1, group2)
print(f"Variable : {variable}")
print(f"Statistique t : {t_statistic}")
print(f"Valeur de p : {p_value}")
# Interprétation du résultat
if p_value < 0.05:
print("La variable a un effet significatif sur la variable cible.")
else:
print("La variable n'a pas un effet significatif sur la variable cible.")
print("\n")
Variable : age Statistique de l'ANOVA : 0.6171088522695939 Valeur de p : 0.4323101436807433 La variable n'a pas un effet significatif sur la variable cible. Variable : anciennete_bancaire_mois Statistique de l'ANOVA : 1.2618930784663216 Valeur de p : 0.2615632079183595 La variable n'a pas un effet significatif sur la variable cible. Variable : solde_fin_mois Statistique de l'ANOVA : 0.1260112247507524 Valeur de p : 0.7226791288264134 La variable n'a pas un effet significatif sur la variable cible. Variable : salaire Statistique de l'ANOVA : 0.2151846783726524 Valeur de p : 0.6428348633693814 La variable n'a pas un effet significatif sur la variable cible. Variable : age Statistique t : 0.7855627615089662 Valeur de p : 0.4323101436809963 La variable n'a pas un effet significatif sur la variable cible. Variable : anciennete_bancaire_mois Statistique t : -1.123340143708183 Valeur de p : 0.2615632079182105 La variable n'a pas un effet significatif sur la variable cible. Variable : solde_fin_mois Statistique t : -0.35498059771028745 Valeur de p : 0.7226791288265757 La variable n'a pas un effet significatif sur la variable cible. Variable : salaire Statistique t : -0.46388002583928556 Valeur de p : 0.6428348633695857 La variable n'a pas un effet significatif sur la variable cible.
import pandas as pd
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
# Supposons que vous avez déjà chargé votre jeu de données dans un DataFrame df.
# Séparez vos données en variables explicatives (X) et la variable cible (y)
X = df.drop('target', axis=1)
y = df['target']
# Divisez vos données en ensembles d'entraînement et de test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Créez le modèle que vous souhaitez utiliser pour la sélection de fonctionnalités
model = LogisticRegression()
# Créez l'objet RFE avec le modèle et le nombre de fonctionnalités à sélectionner
num_features_to_select = 5 # Vous pouvez ajuster ce nombre en fonction de vos besoins
rfe = RFE(model, n_features_to_select=num_features_to_select)
# Adaptez RFE sur vos données d'entraînement
fit = rfe.fit(X_train, y_train)
# Affichez les fonctionnalités sélectionnées
print("Numéro de fonctionnalités sélectionnées:", fit.n_features_)
print("Rang des fonctionnalités sélectionnées:", fit.ranking_)
# Vous pouvez maintenant utiliser les fonctionnalités sélectionnées pour entraîner votre modèle final.
--------------------------------------------------------------------------- ImportError Traceback (most recent call last) Input In [501], in <cell line: 2>() 1 import pandas as pd ----> 2 from sklearn.feature_selection import RFE 3 from sklearn.linear_model import LogisticRegression 4 from sklearn.model_selection import train_test_split File ~\anaconda3\lib\site-packages\sklearn\feature_selection\__init__.py:8, in <module> 1 """ 2 The :mod:`sklearn.feature_selection` module implements feature selection 3 algorithms. It currently includes univariate filter selection methods and the 4 recursive feature elimination algorithm. 5 """ 7 from ._base import SelectorMixin ----> 8 from ._from_model import SelectFromModel 9 from ._mutual_info import mutual_info_classif, mutual_info_regression 10 from ._rfe import RFE, RFECV File ~\anaconda3\lib\site-packages\sklearn\feature_selection\_from_model.py:9, in <module> 5 from numbers import Integral, Real 7 import numpy as np ----> 9 from ..base import BaseEstimator, MetaEstimatorMixin, _fit_context, clone 10 from ..exceptions import NotFittedError 11 from ..utils._param_validation import HasMethods, Interval, Options ImportError: cannot import name '_fit_context' from 'sklearn.base' (C:\Users\Utilisateur\anaconda3\lib\site-packages\sklearn\base.py)
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_iris
# Load the Iris dataset
iris = load_iris()
iris_data = iris.data
iris_target = iris.target
# Diviser les données en ensembles d'entraînement et de test
X_train, X_test, y_train, y_test = train_test_split(iris_data ,iris_target, test_size=0.2, random_state=42)
# Créer un modèle de régression linéaire avec régularisation L1 (Lasso)
lasso_model = Lasso(alpha=0.1) # Le paramètre alpha contrôle la force de la régularisation L1
# Entraîner le modèle sur les données d'entraînement
lasso_model.fit(X_train, y_train)
# Faire des prédictions sur l'ensemble de test
y_pred = lasso_model.predict(X_test)
# Calculer l'erreur quadratique moyenne (MSE) des prédictions
mse = mean_squared_error(y_test, y_pred)
print(f'Erreur quadratique moyenne (MSE) : {mse}')
# Afficher les coefficients du modèle
coefficients = lasso_model.coef_
print('Coefficients du modèle :')
for feature, coef in zip(iris.feature_names, coefficients):
print(f'{feature}: {coef:.2f}')
# Tracer les prédictions par rapport aux valeurs réelles
plt.scatter(y_test, y_pred)
plt.xlabel("Valeurs réelles")
plt.ylabel("Prédictions")
plt.title("Prédictions vs Valeurs réelles")
plt.show()
Erreur quadratique moyenne (MSE) : 0.06677344873438022 Coefficients du modèle : sepal length (cm): 0.00 sepal width (cm): -0.00 petal length (cm): 0.41 petal width (cm): 0.00
r = pd.DataFrame()
r['var']= pd.DataFrame(iris.feature_names)
r['coef'] = pd.DataFrame(abs(lasso_model.coef_))
r
| var | coef | |
|---|---|---|
| 0 | sepal length (cm) | 0.000000 |
| 1 | sepal width (cm) | 0.000000 |
| 2 | petal length (cm) | 0.407829 |
| 3 | petal width (cm) | 0.000000 |
Effectivement, modifier l'hyperparamètre alpha dans la régression Lasso (L1) peut avoir un impact sur la régularisation et, par conséquent, sur les coefficients des variables. Voici comment vous pourriez aborder cette modification :
Réduction d'alpha : Si vous réduisez la valeur de l'hyperparamètre alpha vers zéro, vous réduirez la force de la régularisation L1. Cela signifie que les coefficients des variables auront moins tendance à être contraints vers zéro. En conséquence, les variables qui avaient des coefficients proches de zéro avec une régularisation plus forte pourraient maintenant avoir des coefficients plus importants. Cela pourrait augmenter l'impact de ces variables sur la prédiction.
Validation croisée pour le réglage d'alpha : Pour déterminer la valeur optimale d'alpha, il est courant d'utiliser la validation croisée. Vous pouvez diviser vos données d'entraînement en plusieurs plis, ajuster le modèle Lasso avec différentes valeurs d'alpha sur ces plis, puis évaluer la performance du modèle à l'aide d'une métrique appropriée (comme l'erreur quadratique moyenne) sur les données de validation. L'alpha qui donne la meilleure performance sur la validation croisée peut être choisi comme valeur optimale.
from sklearn.linear_model import LassoCV
# Créer un modèle LassoCV avec une plage d'alphas à tester
alphas = [0.001, 0.01, 0.1, 1.0, 10.0]
lasso_cv_model = LassoCV(alphas=alphas, cv=5)
# Ajuster le modèle sur les données d'entraînement
lasso_cv_model.fit(X_train, y_train)
# Trouver la meilleure valeur d'alpha
best_alpha = lasso_cv_model.alpha_
print("Meilleure valeur d'alpha:", best_alpha)
# Utiliser le modèle avec la meilleure valeur d'alpha pour les prédictions
y_pred = lasso_cv_model.predict(X_test)
# Évaluer la performance du modèle
mse = mean_squared_error(y_test, y_pred)
print(f'Erreur quadratique moyenne (MSE) : {mse}')
# Afficher les coefficients du modèle
coefficients = lasso_cv_model.coef_
print('Coefficients du modèle :')
for feature, coef in zip(iris.feature_names, coefficients):
print(f'{feature}: {coef:.2f}')
# Tracer les prédictions par rapport aux valeurs réelles
plt.scatter(y_test, y_pred)
plt.xlabel("Valeurs réelles")
plt.ylabel("Prédictions")
plt.title("Prédictions vs Valeurs réelles")
plt.show()
Meilleure valeur d'alpha: 0.001 Erreur quadratique moyenne (MSE) : 0.03727803272976116 Coefficients du modèle : sepal length (cm): -0.11 sepal width (cm): -0.05 petal length (cm): 0.26 petal width (cm): 0.53
r = pd.DataFrame()
r['var']= pd.DataFrame(iris.feature_names)
r['coef'] = pd.DataFrame(abs(lasso_cv_model.coef_))
r
| var | coef | |
|---|---|---|
| 0 | sepal length (cm) | 0.112744 |
| 1 | sepal width (cm) | 0.054927 |
| 2 | petal length (cm) | 0.259965 |
| 3 | petal width (cm) | 0.532407 |
import pandas as pd
import numpy as np
import scipy.stats
# Générer des données aléatoires
n_samples = 100
data = {
'variable1': np.random.randn(n_samples),
'variable2': np.random.randn(n_samples)
}
# Créer un DataFrame
df = pd.DataFrame(data)
# Calculer la corrélation de Pearson entre les deux variables
correlation_coefficient, p_value = scipy.stats.pearsonr(df['variable1'], df['variable2'])
# Afficher le coefficient de corrélation et la valeur de p
print(f'Coefficient de corrélation de Pearson : {correlation_coefficient}')
print(f'Valeur de p : {p_value}')
# Interpréter la corrélation
if p_value < 0.05: # seuil de signification de 5%
if correlation_coefficient > 0:
print('Il existe une corrélation positive significative entre les variables.')
elif correlation_coefficient < 0:
print('Il existe une corrélation négative significative entre les variables.')
else:
print('Les variables sont parfaitement corrélées de manière linéaire.')
else:
print('Il n\'y a pas de corrélation significative entre les variables.')
Coefficient de corrélation de Pearson : -0.044144405200800096 Valeur de p : 0.6627593110679328 Il n'y a pas de corrélation significative entre les variables.
import pandas as pd
import numpy as np
from scipy.stats import pearsonr
# Sélectionner toutes les variables numériques à l'exception de la variable cible
numeric_variables = [col for col in df.columns if col != 'target']
# Boucle pour calculer la corrélation de Pearson entre chaque variable numérique et la variable cible
for variable in numeric_variables:
correlation_coefficient, p_value = pearsonr(df[variable], df['target'])
print(f"Variable : {variable}")
print(f"Statistique de corrélation de Pearson : {correlation_coefficient}")
print(f"Valeur de p : {p_value}")
if p_value < 0.05:
print("La variable a un effet significatif sur la variable cible.\n")
else:
print("La variable n'a pas un effet significatif sur la variable cible.\n")
Variable : id Statistique de corrélation de Pearson : 0.018537490483180902 Valeur de p : 0.5581953993977585 La variable n'a pas un effet significatif sur la variable cible.
--------------------------------------------------------------------------- UFuncTypeError Traceback (most recent call last) Input In [361], in <cell line: 10>() 9 # Boucle pour calculer la corrélation de Pearson entre chaque variable numérique et la variable cible 10 for variable in numeric_variables: ---> 11 correlation_coefficient, p_value = pearsonr(df[variable], df['target']) 12 print(f"Variable : {variable}") 13 print(f"Statistique de corrélation de Pearson : {correlation_coefficient}") File ~\anaconda3\lib\site-packages\scipy\stats\_stats_py.py:4432, in pearsonr(x, y, alternative) 4427 return result 4429 # dtype is the data type for the calculations. This expression ensures 4430 # that the data type is at least 64 bit floating point. It might have 4431 # more precision if the input is, for example, np.longdouble. -> 4432 dtype = type(1.0 + x[0] + y[0]) 4434 if n == 2: 4435 r = dtype(np.sign(x[1] - x[0])*np.sign(y[1] - y[0])) UFuncTypeError: ufunc 'add' cannot use operands with types dtype('float64') and dtype('<M8[ns]')
import pandas as pd
from scipy.stats import spearmanr
# Sélectionner toutes les variables numériques à l'exception de la variable cible
numeric_variables = [col for col in df.columns if col != 'target']
# Boucle pour calculer la corrélation de Spearman entre chaque variable numérique et la variable cible
for variable in numeric_variables:
correlation_coefficient, p_value = spearmanr(df[variable], df['target'])
print(f"Variable : {variable}")
print(f"Coefficient de corrélation de Spearman : {correlation_coefficient}")
print(f"Valeur de p : {p_value}")
if p_value < 0.05:
print("La variable a un effet significatif sur la variable cible.\n")
else:
print("La variable n'a pas un effet significatif sur la variable cible.\n")
Variable : id Coefficient de corrélation de Spearman : 0.0185374904831809 Valeur de p : 0.5581953993976974 La variable n'a pas un effet significatif sur la variable cible.
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Input In [363], in <cell line: 8>() 7 # Boucle pour calculer la corrélation de Spearman entre chaque variable numérique et la variable cible 8 for variable in numeric_variables: ----> 9 correlation_coefficient, p_value = spearmanr(df[variable], df['target']) 10 print(f"Variable : {variable}") 11 print(f"Coefficient de corrélation de Spearman : {correlation_coefficient}") File ~\anaconda3\lib\site-packages\scipy\stats\_stats_py.py:4862, in spearmanr(a, b, axis, nan_policy, alternative) 4860 b, _ = _chk_asarray(b, axis) 4861 if axisout == 0: -> 4862 a = np.column_stack((a, b)) 4863 else: 4864 a = np.row_stack((a, b)) File <__array_function__ internals>:5, in column_stack(*args, **kwargs) File ~\anaconda3\lib\site-packages\numpy\lib\shape_base.py:656, in column_stack(tup) 654 arr = array(arr, copy=False, subok=True, ndmin=2).T 655 arrays.append(arr) --> 656 return _nx.concatenate(arrays, 1) File <__array_function__ internals>:5, in concatenate(*args, **kwargs) TypeError: The DTypes <class 'numpy.dtype[int32]'> and <class 'numpy.dtype[datetime64]'> do not have a common DType. For example they cannot be stored in a single array unless the dtype is `object`.
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import f_classif
# Créez un objet SelectKBest avec le test F comme score_func
k_best = SelectKBest(score_func=f_classif, k=5) # Sélectionnez les 5 meilleures caractéristiques
# Appliquez la sélection de caractéristiques aux données X et à la variable cible y
X_new = k_best.fit_transform(X, y)
# Les 5 meilleures caractéristiques sont maintenant dans X_new
# Importer les bibliothèques nécessaires
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
# Créer un jeu de données factice (remplacez ceci par vos données réelles)
data = {
'Feature1': np.random.randn(100),
'Feature2': np.random.randn(100),
'Target': np.random.choice([0, 1], size=100)
}
# Créer un DataFrame à partir du jeu de données
df = pd.DataFrame(data)
# Diviser les données en variables explicatives (X) et variable cible (y)
X = df[['Feature1', 'Feature2']]
y = df['Target']
# Diviser les données en ensembles d'entraînement et de test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Créer un modèle de régression logistique
model = LogisticRegression()
# Entraîner le modèle sur les données d'entraînement
model.fit(X_train, y_train)
# Prédictions sur l'ensemble de test
y_pred = model.predict(X_test)
# Évaluer les performances du modèle
accuracy = accuracy_score(y_test, y_pred)
confusion = confusion_matrix(y_test, y_pred)
classification_rep = classification_report(y_test, y_pred)
print(f"Accuracy : {accuracy}")
print(f"Matrice de confusion : \n{confusion}")
print(f"Rapport de classification : \n{classification_rep}")
# Afficher les coefficients et l'interception du modèle
print("\nCoefficients du modèle :")
print(model.coef_)
print("\nInterception du modèle :")
print(model.intercept_)
# Importez les bibliothèques nécessaires
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
# Créez un jeu de données fictif (exemple)
np.random.seed(42)
X = np.random.rand(100, 2) # Variables explicatives (2 caractéristiques)
y = np.random.randint(0, 2, 100) # Variable cible binaire (0 ou 1)
# Divisez le jeu de données en ensembles d'entraînement et de test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Entraînez un arbre de décision
dt_classifier = DecisionTreeClassifier(random_state=42)
dt_classifier.fit(X_train, y_train)
# Prédictions avec l'arbre de décision
y_pred_dt = dt_classifier.predict(X_test)
# Évaluez les performances de l'arbre de décision
accuracy_dt = accuracy_score(y_test, y_pred_dt)
print("Accuracy de l'arbre de décision:", accuracy_dt)
# Générez un rapport de classification
print("Rapport de classification de l'arbre de décision:")
print(classification_report(y_test, y_pred_dt))
# Affichez la matrice de confusion
conf_matrix_dt = confusion_matrix(y_test, y_pred_dt)
print("Matrice de confusion de l'arbre de décision:")
print(conf_matrix_dt)
# Importation des bibliothèques nécessaires
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
# Génération de données fictives
np.random.seed(42)
X = np.random.rand(100, 2)
y = (X[:, 0] + X[:, 1] > 1).astype(int)
# Création d'un DataFrame pandas
df = pd.DataFrame({'Feature1': X[:, 0], 'Feature2': X[:, 1], 'Target': y})
# Séparation des données en ensemble d'entraînement et ensemble de test
X_train, X_test, y_train, y_test = train_test_split(df[['Feature1', 'Feature2']], df['Target'], test_size=0.2, random_state=42)
# Entraînement d'un arbre de décision
tree_classifier = DecisionTreeClassifier(random_state=42)
tree_classifier.fit(X_train, y_train)
# Prédiction avec l'arbre de décision
y_pred_tree = tree_classifier.predict(X_test)
# Évaluation de l'arbre de décision
accuracy_tree = accuracy_score(y_test, y_pred_tree)
conf_matrix_tree = confusion_matrix(y_test, y_pred_tree)
class_report_tree = classification_report(y_test, y_pred_tree)
print("Arbre de décision - Accuracy:", accuracy_tree)
print("Matrice de confusion - Arbre de décision:\n", conf_matrix_tree)
print("Rapport de classification - Arbre de décision:\n", class_report_tree)
# Après l'entraînement de votre arbre de décision (comme dans l'exemple précédent)
# Accédez aux importances des fonctionnalités
feature_importances = tree_classifier.feature_importances_
feature_names = X_train.columns
# Affichez l'importance de chaque fonctionnalité
for feature_name, importance in zip(feature_names, feature_importances):
print(f"{feature_name}: {importance}")
# Supposons que 'tree_classifier' est votre modèle d'arbre de décision déjà entraîné
importances = tree_classifier.feature_importances_
feature_names = X_train.columns # Noms de vos fonctionnalités
# Créez un DataFrame pour afficher les importances des fonctionnalités
feature_importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': importances})
feature_importance_df = feature_importance_df.sort_values(by='Importance', ascending=False)
# Affichez le classement des fonctionnalités par ordre d'importance
print(feature_importance_df)
# Entraînez une forêt aléatoire
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)
rf_classifier.fit(X_train, y_train)
# Prédictions avec la forêt aléatoire
y_pred_rf = rf_classifier.predict(X_test)
# Évaluez les performances de la forêt aléatoire
accuracy_rf = accuracy_score(y_test, y_pred_rf)
print("\nAccuracy de la forêt aléatoire:", accuracy_rf)
# Générez un rapport de classification pour la forêt aléatoire
print("Rapport de classification de la forêt aléatoire:")
print(classification_report(y_test, y_pred_rf))
# Affichez la matrice de confusion pour la forêt aléatoire
conf_matrix_rf = confusion_matrix(y_test, y_pred_rf)
print("Matrice de confusion de la forêt aléatoire:")
print(conf_matrix_rf)
# Visualisez l'importance des caractéristiques dans la forêt aléatoire
feature_importances = rf_classifier.feature_importances_
plt.figure(figsize=(8, 4))
plt.bar(range(X.shape[1]), feature_importances, tick_label=['Feature 1', 'Feature 2'])
plt.xlabel('Caractéristiques')
plt.ylabel('Importance')
plt.title('Importance des Caractéristiques dans la Forêt Aléatoire')
plt.show()
# Entraînement d'une forêt aléatoire
rf_classifier = RandomForestClassifier(random_state=42)
rf_classifier.fit(X_train, y_train)
# Prédiction avec la forêt aléatoire
y_pred_rf = rf_classifier.predict(X_test)
# Évaluation de la forêt aléatoire
accuracy_rf = accuracy_score(y_test, y_pred_rf)
conf_matrix_rf = confusion_matrix(y_test, y_pred_rf)
class_report_rf = classification_report(y_test, y_pred_rf)
print("\nForêt aléatoire - Accuracy:", accuracy_rf)
print("Matrice de confusion - Forêt aléatoire:\n", conf_matrix_rf)
print("Rapport de classification - Forêt aléatoire:\n", class_report_rf)
# Visualisation de l'importance des fonctionnalités pour la forêt aléatoire
feature_importances = rf_classifier.feature_importances_
feature_names = X_train.columns
plt.barh(feature_names, feature_importances)
plt.xlabel('Importance des fonctionnalités')
plt.ylabel('Fonctionnalités')
plt.title('Importance des fonctionnalités - Forêt aléatoire')
plt.show()
# Après l'entraînement de votre forêt aléatoire (comme dans l'exemple précédent)
# Accédez aux importances des fonctionnalités
feature_importances = rf_classifier.feature_importances_
feature_names = X_train.columns
# Affichez l'importance de chaque fonctionnalité
for feature_name, importance in zip(feature_names, feature_importances):
print(f"{feature_name}: {importance}")
# Supposons que 'rf_classifier' est votre modèle de forêt aléatoire déjà entraîné
importances = rf_classifier.feature_importances_
feature_names = X_train.columns # Noms de vos fonctionnalités
# Créez un DataFrame pour afficher les importances des fonctionnalités
feature_importance_df = pd.DataFrame({'Feature': feature_names, 'Importance': importances})
feature_importance_df = feature_importance_df.sort_values(by='Importance', ascending=False)
# Affichez le classement des fonctionnalités par ordre d'importance
print(feature_importance_df)
import pandas as pd
import numpy as np
from scipy import stats
# Générer des données fictives
n_samples = 3000000 # 3 millions d'échantillons
data = {
'id': range(1, n_samples + 1),
'age': np.random.randint(20, 70, size=n_samples),
'solde_fin_mois': np.random.uniform(-5000, 50000, size=n_samples),
'salaire': np.random.uniform(1000, 10000, size=n_samples),
'target': np.random.choice([0, 1], size=n_samples, p=[0.8, 0.2])
}
# Créer un DataFrame à partir des données
df = pd.DataFrame(data)
# Séparer les données en deux groupes en fonction de la variable cible
groupe_0 = df[df['target'] == 0]
groupe_1 = df[df['target'] == 1]
# Variables à tester
variables_a_tester = ['age', 'solde_fin_mois', 'salaire']
# Effectuer un test t de Student pour chaque variable
for variable in variables_a_tester:
t_stat, p_value = stats.ttest_ind(groupe_0[variable], groupe_1[variable], equal_var=False)
alpha = 0.05 # Niveau de signification
print(f"Variable : {variable}")
print(f"Statistique t : {t_stat}")
print(f"Valeur de p : {p_value}")
if p_value < alpha:
print("La variable a un effet significatif sur la variable cible.")
else:
print("La variable n'a pas un effet significatif sur la variable cible.")
print("\n")
Variable : age Statistique t : -0.7133729899896145 Valeur de p : 0.47561516258504977 La variable n'a pas un effet significatif sur la variable cible. Variable : solde_fin_mois Statistique t : 0.15927731640675583 Valeur de p : 0.8734504263175238 La variable n'a pas un effet significatif sur la variable cible. Variable : salaire Statistique t : -0.7272356877100684 Valeur de p : 0.4670817721744749 La variable n'a pas un effet significatif sur la variable cible.
import pandas as pd
from scipy import stats
# Charger vos données (remplacez 'votre_fichier.csv' par votre fichier de données)
data = pd.read_csv('votre_fichier.csv')
# Spécifiez le nom de votre variable cible (changez 'cible' par le nom réel)
variable_cible = 'cible'
# Créez une liste pour stocker les résultats du test de Student
resultats_tests_student = []
# Boucle à travers toutes les variables explicatives numériques
for variable_explicative in data.columns:
if variable_explicative != variable_cible and data[variable_explicative].dtype == 'float64':
groupe_0 = data[data[variable_cible] == 0][variable_explicative]
groupe_1 = data[data[variable_cible] == 1][variable_explicative]
# Effectuez le test de Student
t_statistic, p_value = stats.ttest_ind(groupe_0, groupe_1, equal_var=False)
# Stockez les résultats dans la liste
resultats_tests_student.append({
'Variable Explicative': variable_explicative,
'T-Statistic': t_statistic,
'P-Value': p_value
})
# Créez un DataFrame pour afficher les résultats
resultats_df = pd.DataFrame(resultats_tests_student)
# Affichez les résultats triés par p-valeur (plus petites p-valeurs d'abord)
resultats_df = resultats_df.sort_values(by='P-Value')
print(resultats_df)
Cette méthode est spécifiquement conçue pour évaluer la corrélation entre une variable binaire et une variable numérique. Elle peut être utilisée pour mesurer la force de la relation entre une variable binaire (par exemple, le comportement) et une variable continue (par exemple, le revenu).
import pandas as pd
from scipy import stats
# Exemple de données fictives
data = pd.DataFrame({
'Variable1': [0, 1, 0, 1, 0],
'Variable2': [25, 30, 35, 40, 45],
'Variable3': [0, 0, 1, 1, 0],
'Cible': [0, 1, 1, 0, 1]
})
# Boucle pour l'analyse de corrélation de point bisérial
target_variable = 'Cible'
correlations = {}
for column in data.columns:
if column != target_variable:
correlation, p_value = stats.pointbiserialr(data[column], data[target_variable])
correlations[column] = {'correlation': correlation, 'p_value': p_value}
# Afficher les résultats
for variable, values in correlations.items():
print(f'Variable: {variable}')
print(f'Corrélation de point bisérial: {values["correlation"]}')
print(f'p-value: {values["p_value"]}')
print('---')
Créez une matrice de corrélation pour visualiser les corrélations entre toutes les paires de variables numériques, y compris la variable cible. Les graphiques de chaleur peuvent être très utiles pour identifier les tendances de corrélation
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# Chargez vos données (remplacez 'votre_fichier.csv' par le nom de votre fichier de données)
#data = pd.read_csv('votre_fichier.csv')
# Supprimez les colonnes non numériques si nécessaire
data_numerical = data.select_dtypes(include=['number'])
# Calculez la matrice de corrélation
correlation_matrix = data_numerical.corr()
# Créez une figure et un axe
plt.figure(figsize=(10, 8))
# Utilisez Seaborn pour créer un heatmap de la matrice de corrélation
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt=".2f")
# Ajoutez des titres aux axes
plt.title('Matrice de Corrélation')
# Affichez le plot
plt.show()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [388], in <cell line: 9>() 3 import matplotlib.pyplot as plt 5 # Chargez vos données (remplacez 'votre_fichier.csv' par le nom de votre fichier de données) 6 #data = pd.read_csv('votre_fichier.csv') 7 8 # Supprimez les colonnes non numériques si nécessaire ----> 9 data_numerical = data.select_dtypes(include=['number']) 11 # Calculez la matrice de corrélation 12 correlation_matrix = data_numerical.corr() AttributeError: 'dict' object has no attribute 'select_dtypes'
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Créer un dataframe fictif pour l'exemple
data = {
'Variable1': [1.0, 2.0, 3.0, 4.0, 5.0],
'Variable2': [2.0, 3.0, 4.0, 5.0, 6.0],
'Variable3': [3.0, 4.0, 5.0, 6.0, 7.0],
'Variable4': [4.0, 5.0, 6.0, 7.0, 8.0]
}
df = pd.DataFrame(data)
# Calculer la matrice de corrélation
correlation_matrix = df.corr()
# Créer une heatmap pour visualiser la matrice de corrélation
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', linewidths=0.5)
plt.title('Matrice de Corrélation')
plt.show()
import numpy as np
import pandas as pd
from scipy import stats
# Créez un DataFrame exemple
data = pd.DataFrame({
'Categorie': ['A', 'A', 'B', 'B', 'C', 'C'],
'Valeur': [10, 15, 8, 12, 20, 25]
})
# Séparez les données en groupes en fonction de la variable catégorielle
groupes = [data[data['Categorie'] == categorie]['Valeur'] for categorie in data['Categorie'].unique()]
#print("groupe",groupes)
# Effectuez le test ANOVA
statistique_anova, p_value = stats.f_oneway(*groupes)
# Interprétation des résultats
alpha = 0.05 # Niveau de signification
print(f"Statistique de l'ANOVA : {statistique_anova}")
print(f"Valeur de p : {p_value}")
if p_value < alpha:
print("La variable catégorielle a un effet significatif sur la variable numérique (rejeter l'hypothèse nulle)")
else:
print("La variable catégorielle n'a pas d'effet significatif sur la variable numérique (accepter l'hypothèse nulle)")
Statistique de l'ANOVA : 7.954545454545454 Valeur de p : 0.06319400895412938 La variable catégorielle n'a pas d'effet significatif sur la variable numérique (accepter l'hypothèse nulle)
import pandas as pd
from scipy import stats
# Charger vos données (assurez-vous que la variable cible est de type catégoriel)
data = pd.read_csv('votre_fichier.csv')
# Séparer les variables numériques et la variable cible
variables_numeriques = data.select_dtypes(include='number')
variable_cible = data['votre_variable_cible']
# Initialiser un dictionnaire pour stocker les résultats de l'ANOVA
resultats_anova = {}
# Boucle à travers chaque variable numérique
for variable in variables_numeriques.columns:
# Effectuer l'ANOVA
groupe_1 = variable_cible[variables_numeriques[variable] == 0]
groupe_2 = variable_cible[variables_numeriques[variable] == 1]
statistique_anova, p_value_anova = stats.f_oneway(groupe_1, groupe_2)
# Stocker les résultats dans le dictionnaire
resultats_anova[variable] = {
'Statistique ANOVA': statistique_anova,
'p-value ANOVA': p_value_anova
}
# Afficher les résultats
for variable, resultats in resultats_anova.items():
print(f"Variable : {variable}")
print(f"Statistique ANOVA : {resultats['Statistique ANOVA']}")
print(f"p-value ANOVA : {resultats['p-value ANOVA']}")
print("")
# Vous pouvez également effectuer une correction de Bonferroni pour ajuster les p-valeurs
# Consultez la documentation de scipy.stats pour plus d'informations sur les ajustements.
Dans ce script :
Nous utilisons la bibliothèque statsmodels pour créer un modèle ANOVA pour chaque variable numérique en utilisant ols. Nous extrayons la p-valeur de l'ANOVA et l'ajoutons au DataFrame des résultats. Ensuite, nous utilisons multipletests pour appliquer la correction de Bonferroni aux p-valeurs. Enfin, nous affichons les résultats, y compris les p-valeurs ajustées. Cela vous permettra d'obtenir les p-valeurs ajustées pour chaque variable numérique après avoir effectué l'ANOVA.
import pandas as pd
import statsmodels.api as sm
from statsmodels.formula.api import ols
from statsmodels.stats.multitest import multipletests
# Charger vos données (assurez-vous que la variable cible est de type catégoriel)
data = pd.read_csv('votre_fichier.csv')
# Séparer les variables numériques et la variable cible
variables_numeriques = data.select_dtypes(include='number')
variable_cible = data['votre_variable_cible']
# Créer un DataFrame pour stocker les résultats de l'ANOVA
resultats_anova = pd.DataFrame(columns=['Variable', 'Statistique ANOVA', 'p-value ANOVA'])
# Boucle à travers chaque variable numérique
for variable in variables_numeriques.columns:
# Créer un modèle ANOVA
model = ols(f'{variable} ~ C(variable_cible)', data=data).fit()
table = sm.stats.anova_lm(model, typ=2)
# Extraire la p-valeur
p_value_anova = table.loc['C(variable_cible)', 'PR(>F)']
# Ajouter les résultats au DataFrame
resultats_anova = resultats_anova.append({
'Variable': variable,
'Statistique ANOVA': table.loc['C(variable_cible)', 'F'],
'p-value ANOVA': p_value_anova
}, ignore_index=True)
# Appliquer la correction de Bonferroni
resultats_anova['p-value ajustée'] = multipletests(resultats_anova['p-value ANOVA'], method='bonferroni')[1]
# Afficher les résultats
print(resultats_anova)
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant
# Sélectionner les variables explicatives
variables_explicatives = data[['Revenu_mensuel', 'Dette_mensuelle', 'Âge', 'Score_de_crédit']]
# Ajouter une constante
variables_explicatives = add_constant(variables_explicatives)
# Calculer les VIF
vif = pd.DataFrame()
vif["Variable"] = variables_explicatives.columns
vif["VIF"] = [variance_inflation_factor(variables_explicatives.values, i) for i in range(variables_explicatives.shape[1])]
print(vif)
import pandas as pd
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant
# Créez un jeu de données fictif
data = pd.DataFrame({
'Revenu': [50000, 60000, 75000, 90000, 100000],
'Âge': [35, 42, 28, 50, 47],
'Endettement': [10, 5, 20, 2, 15]
})
# Supposons que vous ayez également une variable cible binaire, que nous n'utiliserons pas ici.
# Sélectionnez uniquement les variables explicatives numériques
variables_explicatives = data[['Revenu', 'Âge', 'Endettement']]
# Ajoutez une constante (intercept) aux données
variables_explicatives = add_constant(variables_explicatives)
# Calculez les VIF
vif = pd.DataFrame()
vif["Variable"] = variables_explicatives.columns
vif["VIF"] = [variance_inflation_factor(variables_explicatives.values, i) for i in range(variables_explicatives.shape[1])]
# Affichez les résultats
print(vif)
Variable VIF 0 const 133.554420 1 Revenu 5.152041 2 Âge 9.223909 3 Endettement 6.356336
La notion de "GVIF" (Generalized Variance Inflation Factor) est généralement associée à l'analyse de la multicollinéarité dans un modèle de régression. Dans le contexte d'un modèle de scoring comportemental, il est essentiel de détecter et de gérer la multicollinéarité, car elle peut avoir un impact significatif sur la stabilité et la fiabilité de votre modèle.
Pour calculer les GVIF et évaluer la multicollinéarité dans un modèle de scoring comportemental, vous pouvez suivre ces étapes :
Préparation des données : Assurez-vous d'avoir déjà préparé vos données, notamment en codant les variables catégorielles, en traitant les valeurs manquantes et en normalisant les variables numériques si nécessaire.
Modélisation du modèle de régression : Construisez votre modèle de scoring comportemental en utilisant une méthode telle que la régression logistique, qui est couramment utilisée pour ce type de tâche.
Calcul des GVIF : Les GVIF peuvent être calculés pour chaque variable explicative (numérique ou catégorielle) pour évaluer la multicollinéarité. Les GVIF sont calculés comme suit :
GVIF(X) = 1 / (1 - R^2) où R^2 est le coefficient de détermination du modèle de régression linéaire multiple pour X.Interprétation des GVIF : Une règle générale est que si le GVIF pour une variable est proche de 1, cela signifie qu'il y a peu de multicollinéarité pour cette variable. En revanche, si le GVIF est significativement plus grand que 1 (par exemple, supérieur à 5), cela suggère une forte multicollinéarité pour cette variable.
Gestion de la multicollinéarité : Si vous identifiez des variables avec des GVIF élevés, vous pouvez envisager les options suivantes pour gérer la multicollinéarité :
Réévaluation du modèle : Après avoir géré la multicollinéarité, réévaluez votre modèle de scoring comportemental pour vous assurer qu'il est plus stable et que les coefficients des variables sont interprétables.
Il est essentiel de noter que la gestion de la multicollinéarité doit être adaptée à votre cas spécifique, en fonction de votre connaissance du domaine et de l'objectif du modèle de scoring comportemental. L'analyse des GVIF est un outil utile pour identifier les variables potentiellement problématiques en termes de multicollinéarité.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
# Supposons que "df" est votre DataFrame
# Boucle à travers toutes les colonnes du DataFrame
for col in df.select_dtypes(include = {'float64':'int32'}).columns:
# Créer une figure avec deux sous-graphiques
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# Tracer un histogramme
axes[0].hist(df[col], bins=30, density=True, alpha=0.6, color='b', label='Histogramme')
axes[0].set_title(f'Histogramme de {col}')
# Tracer une courbe de densité
sns.kdeplot(df[col], ax=axes[1], color='r', label='Densité')
axes[1].set_title(f'Courbe de densité de {col}')
# Tracer un QQ-plot
stats.probplot(df[col], dist='norm', plot=axes[2])
axes[2].set_title(f'QQ-plot de {col}')
# Ajouter des légendes
axes[0].legend()
axes[1].legend()
# Afficher les graphiques
plt.show()
#1. Histogramme : Si l'histogramme semble suivre une forme de cloche symétrique (distribution normale)
#et est centré autour de la moyenne, cela suggère une distribution gaussienne.
#2. Courbe de densité : Une courbe de densité lisse et symétrique est un autre indicateur d'une distribution gaussienne.
#3. QQ-plot : Sur le QQ-plot, si les points suivent approximativement une ligne droite (la ligne de référence),
#cela suggère une distribution normale. Les écarts par rapport à la ligne droite indiquent des déviations par
#rapport à la normalité.
import pandas as pd
from scipy.stats import shapiro, ks_2samp
# Supposons que votre DataFrame s'appelle df
# Boucle à travers les colonnes du DataFrame (à l'exception de la colonne 'target')
for col in df.select_dtypes(include = {'float64':'int32'}).columns:
if col != 'target':
# Effectuer le test de Shapiro-Wilk
stat_shapiro, p_shapiro = shapiro(df[col])
# Effectuer le test de Kolmogorov-Smirnov
stat_ks, p_ks = ks_2samp(df[df['target'] == 0][col], df[df['target'] == 1][col])
# Afficher les résultats
print(f"Variable : {col}")
print(f"Test de Shapiro-Wilk - Statistique : {stat_shapiro}, p-valeur : {p_shapiro}")
if p_shapiro < 0.05:
print("La variable ne suit pas une distribution normale (p < 0.05)\n")
else:
print("La variable suit une distribution normale (p >= 0.05)\n")
print(f"Test de Kolmogorov-Smirnov - Statistique : {stat_ks}, p-valeur : {p_ks}")
if p_ks < 0.05:
print("La variable est significativement différente entre les groupes (p < 0.05)\n")
else:
print("La variable n'est pas significativement différente entre les groupes (p >= 0.05)\n")
Variable : solde_fin_mois Test de Shapiro-Wilk - Statistique : 0.9579070806503296, p-valeur : 2.3305177160482134e-16 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.06097905256620179, p-valeur : 0.5685026027894566 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : cumul_crediteur Test de Shapiro-Wilk - Statistique : 0.9526365399360657, p-valeur : 2.0124955233196666e-17 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.06452989040081808, p-valeur : 0.49627625578420986 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : cumul_debiteur Test de Shapiro-Wilk - Statistique : 0.9544385671615601, p-valeur : 4.5449594266681266e-17 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.06242824609941091, p-valeur : 0.5386831080170172 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : salaire Test de Shapiro-Wilk - Statistique : 0.9557175636291504, p-valeur : 8.21695610998413e-17 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.04658122071029304, p-valeur : 0.8603517748987934 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : mtn_paiement_par_carte Test de Shapiro-Wilk - Statistique : 0.9575316309928894, p-valeur : 1.9438192500091455e-16 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.039768129034686545, p-valeur : 0.9518163988011158 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : mnt_virement Test de Shapiro-Wilk - Statistique : 0.9555411338806152, p-valeur : 7.566955599406491e-17 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.05663774553165327, p-valeur : 0.6606051827384799 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : mtn_versement Test de Shapiro-Wilk - Statistique : 0.9545024037361145, p-valeur : 4.6798742389367505e-17 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.04883343057359205, p-valeur : 0.8198343491835389 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : mtn_paye Test de Shapiro-Wilk - Statistique : 0.9491900205612183, p-valeur : 4.497948436351023e-18 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.04748461408164418, p-valeur : 0.8443073196617432 La variable n'est pas significativement différente entre les groupes (p >= 0.05) Variable : mtn_impaye Test de Shapiro-Wilk - Statistique : 0.9543682932853699, p-valeur : 4.4009026142695666e-17 La variable ne suit pas une distribution normale (p < 0.05) Test de Kolmogorov-Smirnov - Statistique : 0.10166939566747596, p-valeur : 0.06828094021798259 La variable n'est pas significativement différente entre les groupes (p >= 0.05)
import pandas as pd
from sklearn.preprocessing import StandardScaler
# Créer un DataFrame avec des données fictives
dataa = {
'Variable1': [10, 20, 30, 40, 50],
'Variable2': [5, 15, 25, 35, 45],
'Variable3': [2, 4, 6, 8, 10]
}
dfa = pd.DataFrame(dataa)
# Initialiser le transformateur StandardScaler
scaler = StandardScaler()
# Standardiser les données en excluant certaines colonnes (si nécessaire)
columns_to_exclude = [] # Liste des colonnes à exclure de la standardisation
df_scaled = dfa.copy()
# Appliquer la standardisation uniquement aux colonnes non exclues
for col in dfa.columns:
if col not in columns_to_exclude:
df_scaled[col] = scaler.fit_transform(dfa[[col]])
# Afficher le DataFrame standardisé
print(df_scaled)
Variable1 Variable2 Variable3 0 -1.414214 -1.414214 -1.414214 1 -0.707107 -0.707107 -0.707107 2 0.000000 0.000000 0.000000 3 0.707107 0.707107 0.707107 4 1.414214 1.414214 1.414214
dfa
| Variable1 | Variable2 | Variable3 | |
|---|---|---|---|
| 0 | 10 | 5 | 2 |
| 1 | 20 | 15 | 4 |
| 2 | 30 | 25 | 6 |
| 3 | 40 | 35 | 8 |
| 4 | 50 | 45 | 10 |
df_scaled.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5 entries, 0 to 4 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Variable1 5 non-null float64 1 Variable2 5 non-null float64 2 Variable3 5 non-null float64 dtypes: float64(3) memory usage: 248.0 bytes
# Boucle à travers toutes les colonnes du DataFrame
for col in df_scaled.select_dtypes(include = {'float64':'int32'}).columns:
# Créer une figure avec deux sous-graphiques
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# Tracer un histogramme
axes[0].hist(dfa[col], bins=30, density=True, alpha=0.6, color='b', label='Histogramme')
axes[0].set_title(f'Histogramme de {col}')
# Tracer une courbe de densité
sns.kdeplot(dfa[col], ax=axes[1], color='r', label='Densité')
axes[1].set_title(f'Courbe de densité de {col}')
# Tracer un QQ-plot
stats.probplot(dfa[col], dist='norm', plot=axes[2])
axes[2].set_title(f'QQ-plot de {col}')
# Ajouter des légendes
axes[0].legend()
axes[1].legend()
# Afficher les graphiques
plt.show()
#1. Histogramme : Si l'histogramme semble suivre une forme de cloche symétrique (distribution normale)
#et est centré autour de la moyenne, cela suggère une distribution gaussienne.
#2. Courbe de densité : Une courbe de densité lisse et symétrique est un autre indicateur d'une distribution gaussienne.
#3. QQ-plot : Sur le QQ-plot, si les points suivent approximativement une ligne droite (la ligne de référence),
#cela suggère une distribution normale. Les écarts par rapport à la ligne droite indiquent des déviations par
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
# Créer un DataFrame avec des données fictives
data = {
'Variable1': [10, 20, 30, 40, 50],
'Variable2': [5, 15, 25, 35, 45],
'Variable3': [2, 4, 6, 8, 10]
}
df = pd.DataFrame(data)
# Initialiser le transformateur MinMaxScaler
scaler = MinMaxScaler()
# Normaliser les données en excluant certaines colonnes (si nécessaire)
columns_to_exclude = [] # Liste des colonnes à exclure de la normalisation
df_normalized = df.copy()
# Appliquer la normalisation uniquement aux colonnes non exclues
for col in df.columns:
if col not in columns_to_exclude:
df_normalized[col] = scaler.fit_transform(df[[col]])
# Afficher le DataFrame normalisé
print(df_normalized)
import pandas as pd
import matplotlib.pyplot as plt
# Créer un DataFrame avec vos données
data = pd.DataFrame({
'Cible': [0, 1],
'Variable1': [100, 150],
'Variable2': [80, 120],
'Variable3': [120, 90]
})
print(data)
# Sélectionner uniquement les colonnes des variables explicatives (pas la colonne 'Cible')
variables_explicatives = data.columns[1:]
# Nombre de diagrammes par ligne
diagrammes_par_ligne = 2
# Calculer le nombre total de lignes nécessaires
nombre_de_lignes = len(variables_explicatives) // diagrammes_par_ligne
if len(variables_explicatives) % diagrammes_par_ligne != 0:
nombre_de_lignes += 1
# Définir la taille de la figure globale
plt.figure(figsize=(12, 6))
# Couleur du texte (blanc)
text_color = 'white'
# Boucle à travers chaque variable explicative
for i, variable in enumerate(variables_explicatives):
# Créer un sous-tracé pour chaque diagramme circulaire
plt.subplot(nombre_de_lignes, diagrammes_par_ligne, i + 1)
# Extraire les effectifs pour cette variable
effectifs = data[variable].tolist()
# Étiquettes pour les sections du camembert
labels = ['Cible 0', 'Cible 1']
# Créer le graphique circulaire avec des étiquettes en blanc
plt.pie(effectifs, labels=labels, autopct='%1.1f%%', startangle=90, textprops={'color': text_color})
# Titre du sous-graphique en blanc
plt.title(f'Diagramme circulaire pour {variable}', color=text_color)
plt.axis('equal') # Pour s'assurer que le graphique est un cercle
# Ajuster la disposition pour éviter le chevauchement des titres
plt.tight_layout()
# Afficher les diagrammes
plt.show()
Cible Variable1 Variable2 Variable3 0 0 100 80 120 1 1 150 120 90
import matplotlib.pyplot as plt
# Données du tableau
effectifs = [100, 150, 80, 120, 120, 90]
# Étiquettes pour les tranches du graphique
labels = ['Cible 0 - Variable1', 'Cible 1 - Variable1',
'Cible 0 - Variable2', 'Cible 1 - Variable2',
'Cible 0 - Variable3', 'Cible 1 - Variable3']
# Créer un graphique circulaire
plt.figure(figsize=(8, 8))
plt.pie(effectifs, labels=labels, autopct='%1.1f%%', startangle=140)
# Titre du graphique
plt.title('Répartition des variables explicatives en fonction de la cible')
# Afficher le graphique
plt.show()
import nltk
from nltk.util import ngrams
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
# Fonction pour créer des N-grammes
def generate_ngrams(text, n):
tokens = text.split()
n_grams = ngrams(tokens, n)
return [' '.join(gram) for gram in n_grams]
# Charger les noms depuis les fichiers (à adapter en fonction de votre format de fichiers)
with open('fichier1.txt', 'r') as file1:
names1 = file1.read().splitlines()
with open('fichier2.txt', 'r') as file2:
names2 = file2.read().splitlines()
# Prétraitement des noms et création de N-grammes
names1 = [' '.join(generate_ngrams(name.lower(), 2)) for name in names1]
names2 = [' '.join(generate_ngrams(name.lower(), 2)) for name in names2]
# Calcul TF-IDF
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(names1 + names2)
# Calcul de la similarité cosinus
cosine_similarities = cosine_similarity(tfidf_matrix[:len(names1)], tfidf_matrix[len(names1):])
# Créer un DataFrame pour stocker les résultats
results_df = pd.DataFrame(columns=['Nom1', 'Nom2', 'Similarité Cosinus'])
# Remplir le DataFrame avec les résultats
for i, name1 in enumerate(names1):
for j, name2 in enumerate(names2):
similarity = cosine_similarities[i][j]
results_df = results_df.append({'Nom1': name1, 'Nom2': name2, 'Similarité Cosinus': similarity}, ignore_index=True)
# Enregistrer le DataFrame dans un fichier CSV
results_df.to_csv('similarite_cosinus.csv', index=False)